Docker und WordPress

Zwei Welten begegnen sich: Einerseits wollen wir ja auf moderne Weise entwickeln und haben daher auf Docker umgestellt. Andererseits, naja, ist unser Konfigurator-Backend ein WordPress-Plugin (jaja! Wir arbeiten ja dran!). Wie bringt man das zusammen?

Unser Orchester

Das Thema Docker ist natürlich umfangreich. Wir halten es hier so einfach wie möglich. Eine typische Konfigurator-Anwendung besteht bei uns in der Entwicklung aus 4 “Diensten”:

Für jeden dieser Dienste starten wir einen Docker-“Container”. Weil wir das aber nicht händisch machen wollen, nutzen wir docker-compose.yml:

version: "3.5"
services:

  frontend:
    image: webpack:latest
    build:
      context: ../frontend
    working_dir: /projects/plugins/frontend/js
    links:
    - "wordpress:wordpress"
    ports:
    - ${FRONTEND_WEBPACK_DEVSERVER_PORT}:${FRONTEND_WEBPACK_DEVSERVER_PORT}
    volumes:
    - ..:/projects/plugins/frontend
    environment:
    - WEBPACK_DEVSERVER_PORT=${FRONTEND_WEBPACK_DEVSERVER_PORT}
    env_file: .env
    networks:
    - network

    dns:            
    - 8.8.8.8
    - 8.8.4.4
    


  backend:
    image: webpack:latest
    build:
      context: ../backend
    working_dir: /projects/plugins/backend/js
    links:
    - "wordpress:wordpress"
    ports:
    - ${BACKEND_WEBPACK_DEVSERVER_PORT}:${BACKEND_WEBPACK_DEVSERVER_PORT}
    volumes:
    - ..:/projects/plugins/backend
    environment:
    - WEBPACK_DEVSERVER_PORT=${BACKEND_WEBPACK_DEVSERVER_PORT}
    env_file: .env
    networks:
    - network

    dns:            
    - 8.8.8.8
    - 8.8.4.4
    


  wordpress:
    image: wkfg3:latest
    build:
      context: ../wp
    depends_on:
    - db
    links:
    - "db:db"
    ports:
    - ${WORDPRESS_PORT}:80
    - ${WORDPRESS_SCRIPT_READY_PORT}:${WORDPRESS_SCRIPT_READY_PORT}
    volumes:
    - ../project/wp
    environment:
    - WORDPRESS_ACTIVATION_HOOK=wp plugin activate wkfg3_schrankplaner --allow-root
    env_file: .env
    networks:
    - network

    dns:            
    - 8.8.8.8
    - 8.8.4.4
    


  db:
    image: mysql:5.7
    env_file: .env
    networks:
    - network

    dns:            
    - 8.8.8.8
    - 8.8.4.4
    


networks:
    network:
        name: network-net 

Ziemlich lang! Man sieht aber, wie die vier Services definiert und über ein network vernetzt werden. (Diese Datei ist nur ein Auszug, die echte ist noch etwas komplizierter…)

Der Service

Die meisten Services haben ein working_dir. Darin wird ein Dockerfile erwartet, dass definiert, wie ein Container konkret gebaut wird:

FROM php:7.3.10-apache
RUN usermod -u $WWW_DATA_UID www-data;
RUN if [ "${WWW_DATA_GID:-}" ] ; then groupmod -g $WWW_DATA_GID www-data; fi
RUN curl -o /bin/wp https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar \
	curl -o wordpress.tar.gz -fSL "https://wordpress.org/wordpress-${WORDPRESS_VERSION}.tar.gz"; \
	tar -xzf wordpress.tar.gz -C /usr/src/; \
	rm wordpress.tar.gz; \
	chown -R www-data:www-data /usr/src/wordpress; \

COPY docker-entrypoint.sh /usr/local/bin/
COPY start.sh /usr/local/bin/

ENTRYPOINT ["start.sh"]
CMD ["apache2-foreground"]

(Auch diese Datei ist stark verkürzt…)

Die FROM Direktive gibt den Startpunkt für den Bau des Images an und lädt das entsprechende Basis-Image vom Docker Hub Repository herunter. In diesem Fall ein Ubuntu mit Apache und PHP.

Die RUN Befehle werden auf dem neuen Image dann ausgeführt und darin gespeichert. Man sieht hier, wie sowohl WordPress als auch der wp-cli installiert werden. All diese Befehle laufen, wenn das Image gebaut wird.

Das ENTRYPOINT-Script hingegen wird immer aufgerufen, wenn ein Container mit dem Image gestartet wird. In unserem Fall enthält es jetzt z.B. Kommandos zum Aktivieren von Plugins im WordPress:

sudo -u www-data wp core install --allow-root
sudo -u www-data wp plugin uninstall akismet --deactivate
sudo -u www-data wp plugin uninstall hello --deactivate
sudo -u www-data wp plugin activate backend --allow-root

(Du rätst es schon: Auch diese Datei…)

Wie geh’ ich jetzt damit um?

Für unsere Entwickler ist es jetzt ganz einfach, zu einer Entwicklungsumgebung zu kommen:

docker-compose up --detach
docker-compose start

Wie von Zauberhand entstehen die vier Services und nach einiger Zeit kann man einfach mit dem Browser zugreifen (auf dem durch $WORDPRESS_PORT angegebenem Port, s.o.). Ist das Tagwerk erledigt, schreibt man:

docker-compose stop

und kann beruhigt schlafen gehen. Wenn das Projekt dann erfolgreich umgesetzt ist, befreien wir unseren Tastenkasten vom Ballast mit:

docker-compose down

Danach müssen wir dann allerdings beim nächsten Mal von vorn anfangen, denn alle Daten sind gelöscht.

In diesem Sinne: Viel Vergnügen mit Docker!!