Dieses Tutorial ist VALID.

Bitte lies Dir den Disclaimer durch, bevor Du eine Anleitung umsetzt...

Haftungsausschluss / Disclaimer

Viele WordPress Instanzen parallel betreiben

Und damit wären wir am Ende der langen Reise angekommen… In diesem Kapitel werden wir sehen, wie einfach und schnell wir jetzt produktive WordPress Instanzen auf unserem Server hochjagen können :)

Nachdem wir in den vergangenen Tutorials das Rüstzeug und die Voraussetzungen dafür geschaffen haben, ist das Anlegen von weiteren WordPress Containern jetzt eine Sache von wenigen Minuten. Und so geht’s:

In dem Tutorial gehe ich jetzt ein wenig schneller und ohne viel Erklärung vor, da wir ja in den vergangenen Kapiteln die ganzen Segmente recht ausführlich gesehen haben…

Voraussetzungen

Vorbereitungen

Szenario: Wir möchten für folgende Domains neue WordPress Instanzen anlegen:

  • „raser.de“: Die Instanz läuft auf „raser.de“
  • „gametrader.de“: Die Instanz läuft auf „www.gametrader.de“
  • „xp-server.de“ (mit Bindestrich) UND „xpserver.de“ (ohne Bindestrich): Beide Domains sollen auf „wordpress.xp-server.de“ zeigen

Die diversen Weiterleitungen

Was gibt es denn für Möglichkeiten, auf die wir aufpassen müssen?

  • In jedem Fall: Die „http“ auf „https“ Weiterleitungen macht Traefik gleich ganz am Anfang für uns…
  • Eine Subdomain: „wordpress.xp-server.de“ – keine Weiterleitung, nur eine URL.
  • Eine Domain und eine Subdomain: „raser.de“ und „www.raser.de“ – zwei URLs, Weiterleitung erfolgt durch WordPress (www auf „non-www“ und umgekehrt).
  • Zwei oder mehr Domains mit und ohne Subdomain: „xp-server.de“, „www.xp-server.de“, „xpserver.de“ und „www.xpserver.de“. Vier URLs. Alle Weiterleitungen der „nicht-Hauptdomains“ auf die Hauptdomain und „www zu non-www (bzw. anders rum)“ macht Traefik mit der „redirectregex“ Middleware.

Kurzer Ausflug: To „www“ or „not to www“ – that’s the question…

„www.domain.de“ und „domain.de“ sind für den DNS, unsere Maschine und Dienste wie Google oder Bing zwei komplett eigenständige Adressen, die für sie nichts miteinander zu tun haben. Im Normalfall zeigen beide Adressen auf den selben Server, der sich dann intern um die weitere Verschaltung kümmert, damit nach „außen“ nur eine einzige Variante der Domains sichtbar ist. Das ist besonders für unser Google-Ranking wichtig, denn würden beide Varianten (einmal mit und einmal ohne „www“) gleichzeitig abrufbar sein, straft uns Google das als „doppelten Inhalt“ ab. Noch schlimmer: Wenn „domain-A“ und „domain-B“ dann die gleiche Seite ausliefern, wie zum Beispiel oben die „einmal mit“ und „einmal ohne Bindestrich“ Domains. Google geht generell immer davon aus, dass etwas fischig ist, wenn der gleiche Seiteninhalt unter verschiedenen Adressen im Internet abrufbar ist!

Unabhängig davon muss Traefik aber alle Adressen kennen, unter denen eine Seite erreichbar sein soll, da er nur so für alle den Weg zum WordPress Container frei macht und auch nur für die ihm bekannte Adressen von Let’s Encrypt ein Zertifikat beantragen kann.

Alle Varianten können dann noch über „http“ und „https“ abgerufen werden, womit wir dann insgesamt noch mal doppelt so viele Möglichkeiten hätten. Aber da kümmert sich Traefik zum Glück gleich am Anfang darum, dass alle „http“ Zugriffe sofort auf „https“ umgebogen werden.

„www“ auf „non-www“ bzw. „non-www“ auf „www“ Weiterleitungen macht WordPress für uns, da brauchen wir Traefik nicht bemühen.

Kommen wir zu dem einen Spezialfall, bei dem wir die interne Weiterleitung in Traefik brauchen: Mehrere Domains auf den selben Container schalten…

Eine oder mehrere „Nebendomains“ auf eine „Hauptdomain“ umleiten

Haben wir zwei oder mehr Domains für die selbe Seite, müssen wir entscheiden, welche Domain die „Hauptdomain“ unserer Seite werden soll. Danach brauchen wir Umleitungen von allen Nebendomains zur Hauptdomain. In diesem Fall nehm ich die beiden Domains „xp-server.de“ und „xpserver.de“. Die „Bindestrich-Domain“ soll die Haupt-Domain werden…

Wir könnten einfach alle Domains in die „Host“-Zeile des Traefik Labels eintragen und nichts weiter unternehmen. Dann wäre unsere Seite aus dem Internet auf allen Domains erreichbar. Aber leider mit der jeweiligen URL der Domain. Tippe ich „xpserver.de“ wird mir die Seite im Browser auch unter „xpserver.de“ (ohne Bindestrich!) angezeigt. Das wäre der klassiche „duplicate Content“ (weil ich sie auch unter xp-server.de erreichen kann) und Google straft uns dafür ab. Für Google sind das einfach zwei total verschiedene Seiten im Internet, die exakt den gleichen Inhalt aufweisen. Das ist suspekt und wird bestraft.

Das Dilemma lösen wir durch einen „Redirect“ in Traefik. Dieser sorgt dafür, dass die Nebendomains sofort nach der Eingabe ihrer URL auf die Hauptdomain „umgeschrieben“ werden. Tippe ich mit eingerichtetem Redirect „xpserver.de“ (ohne Bindestrich) in den Browser, ändert sich die URL-Zeile dann sofort auf „wordpress.xp-server.de“ (mit Bindestrich!). Es existiert im Internet also nur eine einzige Variante der Seite unter „wordpress.xp-server.de“, auch, wenn wir verschiedene Nebendomains eintippen. Das mag Google und unser Ranking wird durch die Nebendomains dann nicht negativ beeinflusst.

Dieses Thema hat mir einige schlaflose Nächte und viel Kopfweh verursacht, da der Redirect in Traefik über Regex-Regeln abgewickelt wird. Jeder, der sich schon mal mit den „Regular Expressions“ auseinandergesetzt hat weiß, dass man das nur in kleinen Dosen machen sollte. Ansonsten läuft man Gefahr, seinen Verstand zu verlieren.
Leider bin ich hier wieder bei einem alten Dilemma angekommen: Ich hab Regex nicht wirklich durchblickt. Es gibt eine ganze Latte an Beispielen, wie das funktionieren *könnte*. Ich hab „die eine“ Config nicht gefunden. Also gab es tagelang (!) Trial & Error und ich hab was gefunden, das funktioniert. Aber ob das gut ist…? Keine Ahnung!
Sollte jemand unter den geneigten Lesern ein Regex-Experte sein, bitte erleuchtet mich

Wenn ich hier die ganze Regex-Thematik ausbreite, würde das auch den Rahmen der eh schon wieder viel zu langen Anleitung vollends sprengen. Daher hab ich das Regex-Thema in diesen Artikel ausgelagert und beziehe mich unten in der Config auf die entsprechenden Zeilen…

Danke an dieser Stelle auch noch mal für den Hinweis von Eike zum Nextcloud-Container, der gleichzeitig mein Problem mit der Weiterleitung gelöst hat. Ohne ihn und diesen wertvollen Tipp wäre das hier nicht möglich gewesen!

Anzeige *

23 Kommentare zu „Viele WordPress Instanzen parallel betreiben“

  1. Hallo zusammen,

    erstmal vielen Dank Peter! Bin deinen Anleitungen 1:1 gefolgt und habe jetzt einen funktionierenden Server mit mehreren WordPress-Instanzen, Nextcloud, Jitsi usw. Bin absolut begeistert!

    Beim hinzufügen einer zweiten WordPress-Instanz bin ich auf ein Problem gestoßen, vielleicht betrifft das auch andere darum schreibe ich hier nochmal.

    Meine erste WordPress Instanz läuft auf der Domain des Servers einfach als: meinserver.de

    Als ich eine zweite Instanz (meinedomain.de) hinzufügen wollte sind bei WordPress im Health Check und bei Ninja Firewall ein Haufen Fehler aufgetreten. Immer wieder cURL error 7: failed to connect to meinedomain.de:443 connection refused. Ich habe dann nach langem rumprobieren den Fehler weggekriegt indem ich in der docker-compose extra_hosts: server-ip:meinedomain.de hinzugefügt habe. Dadurch wird anscheinend eben dieser Eintrag in die Hosts-Datei des Containers hinzugefügt. Weiß nicht ob das die richtige Lösung ist oder ob ich damit weitere Probleme geschaffen habe, auf jeden Fall funktioniert jetzt alles. Vielleicht hilft das ja jemandem oder jemand, der sich besser auskennt kann das nochmal einordnen.

    LG,

    williw

    1. Peter Fiedler

      Servus Williw,
      danke für die Rückmeldung!

      Wenn Du möchtest, schick mir doch bitte die docker-compose.yml Dateien für beide Domains (mit gelöschten Passwörtern!) an fiedler@cpf.de, dann schau ich drüber, ob mir da was auffällt.
      Bei einer Instanz hatte ich witzigerweise den gleichen curl-Fehler, hab das aber auf ein Plugin geschoben… Vielleicht steckt aber doch noch wo der Teufel im Detail…

      Beste Grüße!
      Peter.

  2. … nach dem ./update-docker.sh hat er unendlich gerödelt
    – hab dann alle wp-Container gestoppt und gelöscht.
    – dann ./upup-docker.sh ausgeführt.
    – WP-Container wurden neu „createt“ – dennoch ist nur PHP 7.4.3 lt WordPress-Login installiert.
    Ist da vielleicht noch irgendein Fehler in der Anleitung?

    Achso: Und das buster-image lässt auch immer noch nicht löschen.

    VG Hardy

    1. Peter Fiedler

      Da gehen mir jetzt so langsam die Ideen aus…
      – Dockerfile vom WordPress Image hat php:7.4-apache
      – Image ist neu gebaut worden
      – Neues Image ist „latest“ getagged
      – Container mit dem neuen „latest“-Image neu gestartet
      – Nun müsste zwingend php v7.4.5 kommen.

      Probier mal zum Löschen von dem php-buster Image „docker rmi -f [id]“.
      Wenn keine Abhängigkeiten mehr da sind, kann man das Ding löschen, aber manchmal braucht man trotzdem die „forced“ Option.

      1. In dem Script ist doch der tagged-befehl drin?
        ### Build WORDPRESS
        #docker pull wordpress:cli-php7.4
        docker build -t wordpress-php74-apache:5.4 /root//docker/wordpress-php74-apache
        docker tag wordpress-php74-apache:5.4 wordpress-php74-apache:latest

        docker rmi -f [d753d5b380a1] fktn immer noch nicht:
        „Error response from daemon: conflict: unable to delete d753d5b380a1 (cannot be forced) – image has dependent child images“

        Mist. :-(

          1. Peter Fiedler

            So was kann bei der Konferei schnell passieren. War ja in meiner Conf auch ein Flüchtigkeitsfehler…

            Wenn er Dich das php Image nicht löschen lässt, ist noch irgendein Image mit dem Ding gebaut und liegt auf dem System. Im Zweifel Image löschen, php löschen. Wenns nicht geht, nächstes Image löschen, php löschen… Bis Du das Image erwischt hast, das blockiert. Danach die Images neu bauen lassen.

          2. …stimmt, kann passieren. Sitze ja nun auch schon einige Zeit am Rechner..
            Ich melde mich morgen nochmal mit meinen „Ergebnissen“.

            Vielen Dank – wir schaffen das! (Zitat von unserer Mutter) :-)

          3. Peter Fiedler

            Bitte sag nicht „Mutter“ zur „großen Vorsitzenden“.

            Aber ja, das werden wir schon hin bekommen ;)

          4. So, ich nochmal.
            Ich hatte zum einen im WordPress Dockerfile einen falschen Hash eingetragen!

            Dann musste ich komplett alle Container und Image löschen um das ganze System zu bereinigen.

            Anschließend beide Scripts ausgeführt und nun ist alles super am Laufen!

            Vielen Dank nochmal Peter.

            ..hab ne Menge gelernt dabei :-)

          5. Peter Fiedler

            Hey super, das freut mich, Hardy!
            Manchmal ist es die berühmte Kleinigkeit, die das Schiff zum Kentern bringt…
            Dann noch viel Spaß mit dem Server :)

  3. Das stimmt etwas nicht: 404 page not found

    root@dockerout:~# docker logs domainA
    AH00558: apache2: Could not reliably determine the server’s fully qualified domain name, using 172.18.0.5. Set the ‚ServerName‘ directive globally to suppress this message
    AH00558: apache2: Could not reliably determine the server’s fully qualified domain name, using 172.18.0.5. Set the ‚ServerName‘ directive globally to suppress this message
    [Sun Apr 19 14:55:31.494573 2020] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.38 (Debian) PHP/7.4.3 configured — resuming normal operations
    [Sun Apr 19 14:55:31.494792 2020] [core:notice] [pid 1] AH00094: Command line: ‚apache2 -D FOREGROUND‘

    kann damit nur nix anfangen…
    Gruß Hardy

    1. Peter Fiedler

      Seltsam, eigentlich sollte die Config so funktionieren…
      Hast Du nicht neulich erst die Updates für den Stack gemacht? Die php-Version ist irgendwie noch die alte.

      Du hast die Tutorials schon 1:1 so übernommen, oder? Wenn da noch was anderes mit reinspielt, kann ich Dir nicht helfen.

      1. Ich habe die docker-compose.yml nur um die Einträge verändert, damit die andere Domain auch diesen Container aufruft – sonst nichts. Ich check nochmal alles. Bist Du Dir sicher, dass diese Konfig nun so richtig ist?: hab die „– „traefik.http.routers.domainA-sec.middlewares=default-headers@file“ entfernt.

        labels:
        – „traefik.enable=true“
        – „traefik.http.routers.domainA.entrypoints=http“
        – „traefik.http.routers.domainA.rule=Host(`domainA.de`,`www.domainA.de`,`domainB.de`,`www.domainB.de`)“
        – „traefik.http.routers.domainA.middlewares=https-redirect@file“
        – „traefik.http.routers.domainA-sec.entrypoints=https“
        – „traefik.http.routers.domainA-sec.rule=Host(`domainA.de`,`www.domainA.de`,domainB.de`,`www.domainB.de)“
        – „traefik.http.middlewares.domainA-redirect.redirectregex.regex=^https:\/\/(www.)?(domainA.de|domainB.de)(.+)?“
        – „traefik.http.middlewares.domainA-redirect.redirectregex.replacement=https://domainA.de$${3}“
        – „traefik.http.middlewares.domainA-redirect.redirectregex.permanent=true“
        – „traefik.http.routers.domainA-sec.middlewares=domainA-redirect,default-headers@file“
        – „traefik.http.routers.domainA-sec.tls=true“
        – „traefik.http.routers.domainA-sec.tls.options=myTLSOptions@file“
        – „traefik.http.routers.domainA-sec.tls.certresolver=le“

        Gruß Hardy

        1. Peter Fiedler

          So weit schauts wie gesagt gut aus…

          Machen wir mal erweitertes Troubleshooting:
          – Die DNS-Einträge sind korrekt gesetzt und domainA wie auch domainB zeigen auf die IP von Deinem Server? Hast Du eine gute Stunde nach der Eintragung gewartet? Das dauert manchmal mit dem DNS…
          – Traefikv2 ist genau nach Tutorial installiert und läuft?
          – Du hast die Datenbank und den Datenbankbenutzer in MariaDB angelegt und die Werte richtig in der docker-compose drin?

          1. Also irgendwie sieht mein php komisch aus:
            root@dockerout:~# docker images
            REPOSITORY TAG IMAGE ID CREATED SIZE
            nextcloud-php74-apache 18.0.3 9a603b326c45 26 hours ago 796MB
            nextcloud-php74-apache latest 9a603b326c45 26 hours ago 796MB
            matomo-php74-apache 3.13.4 5e9ede511571 44 hours ago 541MB
            matomo-php74-apache latest 5e9ede511571 44 hours ago 541MB
            wordpress cli-php7.4 b4f0afa32d83 46 hours ago 138MB
            mariadb 10.4 eef18f9e510d 2 days ago 357MB
            php 7.4-apache 470476c8d529 2 days ago 414MB
            php 7.4.5-apache 470476c8d529 2 days ago 414MB
            traefik v2.1 72bfc37343a4 3 weeks ago 68.9MB
            matomo-php74-apache 3.13.2 0f47fb00b5e3 4 weeks ago 541MB
            wordpress-php74-apache 5.3.2 d5d63c50ddaf 7 weeks ago 608MB
            wordpress-php74-apache latest d5d63c50ddaf 7 weeks ago 608MB
            php 7.4-apache-buster d753d5b380a1 7 weeks ago 414MB

            Wie kann ich die php-images löschen und neu erstellen?
            docker rmi d753d5b380a1
            ergibt:
            Error response from daemon: conflict: unable to delete d753d5b380a1 (cannot be forced) – image has dependent child images

            (Übrigens laufen beide scripts ohne Fehler durch)
            Gruß Hardy

          2. Peter Fiedler

            F**K! Da hab ich einen Fehler im Dockerfile von WordPress :/
            Da gehört in Zeile 4 „php:7.4-apache“ rein, nicht „pho:7.4-apache-buster“.
            Änder bitte das Dockerfile entsprechend und lass das Image neu bauen. Einfach drüberbügeln. Danach müsstest Du das 7.4-apache-buster Image löschen können…

            Bei Matomo auch… Bitte da auch ändern und neu bauen.

          3. Dann kann man das in der Anleitung wohl auch ändern:

            Zeile 4: Das Grundlegende Image, auf dem unser WordPress-Image aufbaut, ist das „php:7.4-apache-buster“. Also ein Debian-10 Image mit Apache und php in Version 7.4. Dieses Image wird beim Bauprozess zuerst geladen. Alle folgenden Instruktionen im Dockerfile erweitern dieses Image dann um die jeweiligen Funktionen und Programme, bis am Schluss unser fertig modifiziertes WordPress Image dabei heraus kommt…..
            „php:7.4-apache“ statt „php:7.4-apache-buster“
            Gruß Hardy

  4. Hallo,
    ich würde gern 2 Domains unter dem gleichen Container erreichbar machen.
    Wären dann die folg.Einstellungen korrekt? Oder dürfen nur die ersten 9 Einträge aktiviert werden – siehe oben in der Anleitung.

    labels:
    – „traefik.enable=true“
    – „traefik.http.routers.domainA.entrypoints=http“
    – „traefik.http.routers.domainA.rule=Host(`domainA.de`,`www.domainA.de`,`domainB.de`,`www.domainB.de`)“
    – „traefik.http.routers.domainA.middlewares=https-redirect@file“
    – „traefik.http.routers.domainA-sec.entrypoints=https“
    – „traefik.http.routers.domainA-sec.rule=Host(`domainA.de`,`www.domainA.de`,domainB.de`,`www.domainB.de)“
    – „traefik.http.middlewares.domainA-redirect.redirectregex.regex=^https:\/\/(www.)?(domainA.de|domainB.de)(.+)?“
    – „traefik.http.middlewares.domainA-redirect.redirectregex.replacement=https://domainA.de$${3}“
    – „traefik.http.middlewares.domainA-redirect.redirectregex.permanent=true“
    – „traefik.http.routers.domainA-sec.middlewares=domainA-redirect,default-headers@file“
    – „traefik.http.routers.domainA-sec.middlewares=default-headers@file“
    – „traefik.http.routers.domainA-sec.tls=true“
    – „traefik.http.routers.domainA-sec.tls.options=myTLSOptions@file“
    – „traefik.http.routers.domainA-sec.tls.certresolver=le“

    VG Hardy

    1. Peter Fiedler

      Servus Hardy,
      die eine Zeile muss raus:
      – „traefik.http.routers.domainA-sec.middlewares=default-headers@file“
      Die default-headers werden in der einen Zeile darüber schon zusammen mit dem Redirect ausgeführt. Das muss in einer Zeile stehen, sonst funktioniert es nicht.

      Ansonsten schaut das gut aus. Einfach testen und das Log anschauen. Im Zweifel steht da drin, was klemmt…

      Beste Grüße
      Peter.

Kommentar verfassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Verwendung
von Cookies

Um unsere Webseite für Sie optimal zu gestalten und fortlaufend verbessern zu können, verwenden wir Cookies. Durch die weitere Nutzung der Webseite stimmen Sie der Verwendung von Cookies zu. Weitere Informationen zu Cookies erhalten Sie in unserer Datenschutzerklärung.

Scroll to Top