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?
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…)
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…)
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!!