WordPress-Entwicklung mit Docker

Web-Entwickler kommen irgendwann zwangsweise mit WordPress in Berührung. Völlig egal, ob es die ersten Gehversuche oder das tägliche Brot sind. Anstatt WordPress-Projekte allerdings jedes Mal mit dem Download der aktuellen Version und dem lokalen LAMP/MAMP/XAMPP/etc Service-Bundle zu starten, kann man der Portabilität zuliebe auch auf Docker zurückgreifen – und genau das zeigen wir euch in diesem Blog-Artikel.

Als Entwickler hat man wohl schon unweigerlich von Docker gehört. Docker ist in aller Munde und die Popularität der Container-Software nimmt weiterhin zu.

Google Search Trend für „docker“

Für alle, die Docker noch nicht kennen: Docker ist eine Software zur Containervirtualisierung. Container deshalb, weil man alle möglichen Programme bzw. Dienste, meist nach Aufgaben getrennt voneinander, in kompakte Pakete (= Container) verpackt. Im Vergleich zu virtuellen Maschinen sollen hier vor allem die Performance und die Portabilität gesteigert werden. Mehr dazu auf der Docker-Webseite www.docker.com.

Wenn wir dieses Konzept also für die Entwicklung von WordPress Plugins oder Themes anwenden wollen, müssen wir uns kurz überlegen, was wir benötigen:

  1. WordPress
  2. Webserver mit PHP
  3. Datenbank (z.B. MySQL)
  4. Optional: phpMyAdmin

Diese Software bzw. Dienste müssen wir nun also in Docker-Container verpacken. Solche Container können wir uns relativ einfach selbst anlegen. Dies ist dank zentraler Anlaufstelle, dem so genannten Docker Hub, mit wenige Zeilen Konfigurationsaufwand möglich, da die verschiedenen Software-Hersteller und die Community schon zahlreiche Images bereitstellen.
Die Konfiguration geschieht in der Datei docker-compose.yml . Diese Datei dient der Definition unserer Services, also welche Container wir wie konfigurieren wollen. Als Syntax kommt hier YAML zum Einsatz.

 

Datenbank

In unserem Falle wählen wir die aktuelle Version von MySQL als Datenbank. Wir vergeben ein root-Passwort und geben den Speicherort für die Datenbank an, damit wir auch in unserem lokalen Dateisystem (Ordner db_data) Zugriff darauf haben.

  mysql:
    image: mysql
    volumes:
      - ./db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: password

 

WordPress

Wir entscheiden uns für das offizielle WordPress-Image als Basis, welches bereits die aktuelle Version von WordPress, sowie einen fertig konfigurierten Webserver mit PHP 7.2 mitbringt. Den Port 80 des Containers mappen wir auf unseren lokalen Port 8080.
Um die Verbindung zur Datenbank herzustellen, geben wir noch das vorhin definierte Passwort an.

Nehmen wir mal an, wir entwickeln gerade ein Plugin, mit dem man Turnierergebnisse eines Spiels in einem bestimmten Format hochladen kann. Die Ergebnisse werden dann ausgelesen und in der Datenbank gesammelt, woraus eine stets aktuelle Rangliste generiert wird. Wir haben also auf unserem lokalen Entwicklungssystem den Source Code dieses Plugins und wollen ihn in den WordPress-Container bringen.
Das machen wir einfach mittels volumes in der Konfiguration. Hier geben wir, wie schon vorher bei der Datenbank, einen lokalen Pfad an, den wir in den Container verlinken wollen.
Mein lokaler Pfad ./wp-content/plugins/mtg_league_tracker im aktuellen Verzeichnis zeigt also auf /var/www/html/wp-content/plugins/mtg_league_tracker im Container.
Gleiches dann nochmal für den Upload-Ordner.

  wordpress:
    depends_on:
      - mysql
    image: wordpress:php7.2
    ports:
      - 8080:80
    restart: always
    environment:
      WORDPRESS_DB_PASSWORD: password
    volumes:
      - ./wp-content/plugins/mtg_league_tracker:/var/www/html/wp-content/plugins/mtg_league_tracker
      - ./wp-content/wp-uploads:/var/www/html/wp-content/wp-uploads

 

phpMyAdmin

Zur einfacheren Überprüfung unserer Datenbank-relevanten WordPress-Entwicklung legen wir noch einen Service für phpMyAdmin an, dem wir das Datenbank-Passwort übergeben und per Port 8081 verfügbar machen.
Weiters sagen wir diesem Dienst per links, dass er unseren vorhin angelegten Datenbank-Service verwenden soll.

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - 8081:80
    links:
      - mysql:db

 

Fügen wir die Bausteine zusammen…

Die fertige docker-compose.yml Datei sieht dann wie folgt aus:

version: '3'

services: 
  mysql:
    image: mysql
    volumes:
      - ./db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: password
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - 8081:80
    links:
      - mysql:db
  wordpress:
    depends_on:
      - mysql
    image: wordpress:php7.2
    ports:
      - 8080:80
    restart: always
    environment:
      WORDPRESS_DB_PASSWORD: password
    volumes:
      - ./wp-content/plugins/mtg_league_tracker:/var/www/html/wp-content/plugins/mtg_league_tracker
      - ./wp-content/wp-uploads:/var/www/html/wp-content/wp-uploads

Über die Kommandozeile können unsere Container dann allesamt gestartet werden:
docker-compose up -d

Nach kurzer Startphase ist die WordPress-Seite dann auch schon per Browser unter http://localhost:8080 erreichbar. phpMyAdmin analog dazu unter http://localhost:8081 .

Um die Container wieder zu stoppen reicht docker-compose stop . Die Datenbank bleibt hierbei erhalten und muss so also nicht bei jedem Start der Container neu eingerichtet werden.
Falls der Debug-Output benötigt wird, können die Logs per docker-compose logs -f eingesehen werden. Alternativ hat man auch die Möglichkeit beim Start die Option -d wegzulassen.

Nach dem erstmaligen Start der Container müssen wir WordPress erstmal einrichten

 

Frohe Entwicklung

Hat alles geklappt, können wir unsere Entwicklung bequem über das lokale Dateisystem erledigen und müssen uns nicht mit Webservern usw. herumschlagen.

Die Ordner-Struktur für unser Beispiel-Plugin sieht ungefähr so aus:

wp_mtg_league/
  -> db_data/
  -> wp-content/
    -> plugins/
      -> mtg_league_tracker/
        -> mtg_league_tracker.php
  -> wp-uploads/
  -> docker-compose.yml

 

Unser Plugin (MTG League Tracker) wurde korrekt vom lokalen Ordner eingebunden

Docker kann uns die Entwicklung also ungemein vereinfachen. Keine lästige Konfiguration der Entwicklungsumgebung auf unterschiedlichen Arbeitsplätzen mehr. Einfach Container anstarten und fertig.

Quellen:

https://developer.wordpress.org/plugins/the-basics/
https://docs.docker.com/compose/wordpress/