Noch schneller geht es kaum: WordPress + Docker

Docker vebindet Einfachheit, Sicherheit und Leistungsfähigkeit. Mit einer Gruppierung von mehreren Containern über eine Docker Compose Gruppe erkläre Ich hier, wie man mit Docker NGINX und WordPress als Container virtualisiert und aufsetzt.

Warum WordPress in Docker statt mit einer traditionellen Installation?

Docker teilt deine WordPress Installation, deinen Webserver und deine Datenbank in einzelne Container, virtuelle Systeme. Du brauchst also keine bestimmten Pakete für PHP, keine manuelle Konfiguration – ein einfacher Befehl reicht und schon läuft die aktuellse Version von WordPress auf deinem System: docker run wordpress:latest
Okay, eine Datenbank ist dann noch nicht enthalten und kein Webserver vermittelt deine Anfragen an WordPress – aber das ist auch so gewollt. Dieser Ansatz nennt sich Separation of concerns und meint die Trennung von Anliegen. In diesem Fall ist das die Trennung von zwischen verschiedener WordPress, MySQL und NGINX und dem ausführenden Server.

Die super einfache Wartbarkeit ist auch ein großer Vorteil. Wir können Container ohne weiteres pausieren, aktualisieren und wieder starten – schon ist die Software und alle Abhängigkeiten auf dem neusten Stand.

Volumes vermitteln Dateisysteme zwischen Container und Host. Nur Volumes persistieren Daten, andernfalls bleiben geschriebene Daten im temporären Laufzeit Speicher des Container Hier gehen dann bei der Erzeugung eines neuen Containers alle Daten verloren, bei einem erstellten Volume können auf die persistenten Daten des Containers wie bei einer lokalen Installation zugegriffen werden.

Auch mehrere WordPress Instanzen lassen sich mit dieser Methode problemlos aufsetzen. Parallel werden die Container dann über eine Datenbank und eine NGINX Instanz verbunden und über den Host angesprochen. So mache Ich das mit allen verwalteten Webseiten ebenfalls!

Wie setze Ich die benötigten WordPress Docker Container auf?

Während einzelne Container in der Regel mit normalen Docker befehlen gesteuert werden, setzt man für das Administrieren von einer logischen Gruppe docker-compose ein.

In der docker-compose.yml Datei setzen wir pro Image einen Service Block auf. Das ganze sieht dann so aus:

version: "3"
services:
  nginx: 
    image: nginx:latest
    restart: always
    container_name: production-nginx
    volumes:
      - /etc/letsencrypt/:/etc/letsencrypt/
      - ./nginx/:/etc/nginx/
    ports:
      - "80:80"
      - "443:443"
  wp:
    image: wordpress:latest
    restart: always
    container_name: production-wordpress
    environment:
      WORDPRESS_DB_HOST: production-db:3306
      WORDPRESS_DB_USER: dbuser
      WORDPRESS_DB_PASSWORD: dbpassword
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - ./wordpress:/var/www/html
  db:
    image: mysql:5.7
    container_name: production-db
    restart: always
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: dbuser
      MYSQL_PASSWORD: dbpassword
      MYSQL_RANDOM_ROOT_PASSWORD: "1"
    volumes:
      - ./mysql:/var/lib/mysql

Hier können wir also sehen, wie wir drei Services erstellen: NGINX, als Webserver und Proxy, MySQL in der empfohlenen Version 5.7 als Datenbank und WordPress selbst.

Wichtig sind die Volumes: Hier werden in lokale Pfade auf dem System Dateien aus dem Container und andersherum eingebunden, der NGINX Container kann also auf die Zertifikate im /etc/letsencrypt/live Pfad und auf Konfigurationen im `nginx` Ordner im Arbeitsverzeichnis zugreifen.

Die Umgebungsvariablen des WordPress und des MySQL Containers sind wichtig für die Initialisierung. MySQL erstellt damit die notwendige WordPress Website, WordPress erstellt damit die notwendige wp_config.php und legt dort alle notwendigen Informationen für die Datenbankverbindung ab.

Der Parameter restart: always gibt zu dem an, dass bei einem Neustart des Systems diese Container sofort gestartet werden sollen und bei einem Fehler im Container neu gestartet werden sollen.

Wer möchte kann die Services darüber hinaus in einem externen Docker Netzwerk verbinden. So können wir den NGINX Service auslagern und als eigenständigen Container betreiben. Pro betriebener Website wird dann eine Datenbank und eine WordPress Instanz in einer docker-compose.yml angegeben und durch den externen NGINX Container angesprochen (auch hier mache Ich das so).

Vorgeschalteter NGINX Container als Reverse Proxy für weitere Container
Vorgeschalteter NGINX Container als Reverse Proxy für weitere Container

Wie konfiguriere Ich den NGINX Reverse Proxy?

events {}
http {
  server_names_hash_bucket_size  64;
  error_log /etc/nginx/error_log.log debug;
  client_max_body_size 20m;
  proxy_cache_path /etc/nginx/cache keys_zone=one:500m max_size=1000m;

  # Redirect all http requests to https
  server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 301 https://$host$request_uri;
  }

  # Redirect requests from https://www.example.com to https://example.com
  server {
    server_name www.example.com;
    listen 443 ssl;
    # Include SSL certificates managed by certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    # Include letsencrypt standards
    include /etc/letsencrypt/options-ssl-nginx.conf;
    # Include proxy settings for docker/wordpress
    include /etc/nginx/includes/proxy.conf;
    # Use docker DNS for proxy resolving
    resolver 127.0.0.11;
    # https://www.example.com -> https://example.com
    rewrite ^/(.*) https://example.com/$1 permanent;
  }
  server {
    server_name example.com;
    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    include /etc/nginx/includes/proxy.conf;
    resolver 127.0.0.11;

    index index.php;
    try_files $uri $uri/ =404;

    # This must match your container_name set in docker-compose.yml!
    set $wordpress http://production-wordpress;

    location / {
      proxy_set_header    X-Forwarded-Host   $host;
      proxy_set_header    X-Forwarded-Server $host;
      proxy_set_header    X-Forwarded-For    $proxy_add_x_forwarded_for;
      proxy_set_header    X-Real-IP          $remote_addr;
      proxy_set_header    Host               $host;
      proxy_set_header    X-Forwarded-Proto https;
      proxy_pass $wordpress;
    }
  }
}

Ich erkläre hier nun kurz die NGINX Konfiguration, bestehend aus folgenden Abschnitten:

  • Zeile 3-6: Caching eingerichtet um Last zu minimieren
  • Zeile 9-14: Alle HTTP Anfragen werden auf HTTPS weitergeleitet
  • Zeile 17-31: Alle HTTPS Anfragen werden von https://www.example.com auf https://example.com weitergeleitet. Das SSL Zertifikat ermöglicht verschlüsselten Traffic.
  • Zeile 32-38: Selbe SSL Einstellungen wie bei der Weiterleitung.
  • Zeile 39: Der DNS von Docker selbst wird hier als resolver angegeben, damit kann weiter unten der Hostname production-wordpress aufgelöst werden.
  • Zeile 47-54: Wir setzen wichtige Proxy Einstellungen. Diese sind zwingend notwendig, damit WordPress alle Informationen erhält die es für richtige Antworten braucht!

Diese Einstellungen sind natürlich auf ein funktionales Minimum beschränkt. Wenn mehrere Websites angeboten werden sollen empfiehlt es sich die Server Blöcke in einzelne Dateien auszulagern. Die Dateien werden dann unter nginx/sites-available abgelegt und nach nginx/sites-enabled verlinkt.

Starten der WordPress Docker Compose Gruppe

Nun haben wir alles konfiguriert und können die Gruppe starten. Dafür reicht der Befehl docker-compose up -d. Dieser bezieht erst Images, also die Grundlagen der Container aus dem Docker Hub. Dann baut der Befehl Container nach unserer Konfiguration. Sobald Docker alles gestartet hat sollte folgende Ausgabe erscheinen:

[...]
Starting production-nginx     ... done
Starting production-wordpress ... done
Starting production-db        ... done

Falls doch Fehler angezeigt werden sollten ist der erste Ort für die Fehlersuche docker-compose logs, welcher die Standardausgabe der Container beinhaltet. Dann sollte bei Erreichbarkeitsproblemen nginx/error.log und nginx/access.log geprüft werden.

Falls es keine Fehler gab dürft Ihr euch nun auf die Einrichtung der WordPress Seite freuen!

Über Fragen oder Kommentare freue Ich mich natürlich wie immer, gerne einfach unten kommentieren oder hier auf Kontakt klicken.

Schreibe einen Kommentar

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