
Erste Schritte
Grundsätzlich kann man bei der Installation der Docker-Anwendung nicht viel falsch machen: Account anlegen, Docker herunterladen, installieren, anmelden – fertig. Auf die zugrunde liegende Technologie will ich hier nicht weiter eingehen, das machen andere weitaus besser (z.B. ist diese Anleitung sehr zu empfehlen). Nur soviel soll gesagt sein: Du lädst ein Image herunter, dass du dann starten kannst. Dadurch erhältst du einen Container, der bestimmte Dienste bereitstellt. Dieser Container ist kein vollständiges Betriebssystem mit all seinem Ballast. So kannst du z.B. nicht ohne weiteres per SSH darauf zugreifen. Das funktioniert nur, wenn der entsprechende SSH-Dienst auch im Image vorgesehen ist. Das schöne an Docker ist aber, dass du das Image mit beliebigen Funktionalitäten über ein sogenanntes Dockerfile relativ unkompliziert nachrüsten kannst. Das erfordert zwar eine gewisse Umgewöhnung im Arbeitsablauf ab, bringt aber auch viele Vorteile mit sich. Wer will kann sich mit der Kitematic UI durch die vorhandenen Docker-Images wühlen und auch direkt herunterladen. Diese stehen dann natürlich auch auf der Kommandozeile zur Verfügung. Mit docker image ls zeigst du alle verfügbaren Images an. Analog dazu listet docker container ls alle erstellten Container auf. Außerdem gibt es noch ein paar andere, für den Anfang ganz brauchbare Befehle:
1 2 3 4 5 6 7 8 |
# alle lokal verfügbaren Images auflisten docker image ls # alle gestarteten bzw. erzeugten Container auflisten docker container ls # die Kommandozeile für den Container mit dem Namen "mysql" die Kommandozeile starten docker exec -it mysql /bin/bash # für den Container mit dem Namen "mysql" das Setup anzeigen docker inspect mysql |

Den MySQL-Container starten
… es mit dem MySQL-Container. Da der nginx-Container auf MySQL zugreift, muss der MySQL-Container auch zuerst dasein. Der Aufruf dafür sieht folgendermaßen aus:
1 2 3 4 5 6 7 8 9 |
docker run \ --name mysql \ --publish 3306:3306 \ --volume /Users/nicky/Development/MySQL:/var/lib/mysql \ --env MYSQL_ALLOW_EMPTY_PASSWORD=yes \ --env MYSQL_ROOT_HOST=% \ --detach \ --default-authentication-plugin=mysql_native_password \ mysql |
Unable to load authentication plugin ‘caching_sha2_passwordUnd schließlich gibt es noch den Parameter –detach, der einfach dafür sorgt, dass der Container im Hintergrund gestartet wird. Das war es fast. Was jetzt noch fehlt, ist der Name des Images, dass die Grundlage für deinen neuen Container bilden soll: mysql. Wenn das Image lokal nicht vorhanden ist, lädt Docker es hilfsbereiterweise einfach herunter. Es empfiehlt sich, den Aufruf in ein Shell-Script zu packen und diese Zeilen voranzustellen. Beim Aufruf wird also ein vorhandener Container erst gestoppt und gelöscht und dann neu gestartet:
1 2 3 4 5 6 7 8 9 10 11 12 |
#!/bin/bash docker stop mysql docker rm mysql docker run \ --name mysql \ -p 3306:3306 \ -v /Users/nicky/Development/MySQL:/var/lib/mysql \ -e MYSQL_ALLOW_EMPTY_PASSWORD=yes \ -e MYSQL_ROOT_HOST=% \ -d \ --default-authentication-plugin=mysql_native_password \ mysql |
Den HTTP-Container starten
Am Vorgehen ändert sich nicht viel. Auch für den nginx-Server erstelle ich mir ein kleines Script. Dieses befindet sich aber in einem Unterordner meiner WordPress-Installation. Mit dem Platzhalter ${PWD} im Parameter –volume kann ich Docker das aktuelle Verzeichnis mitgeben. Dadurch kann ich das Script auch innerhalb andere WordPress-Installationen verwenden (und muss lediglich den Namen des Containers anpassen). Hier sorge ich also dafür, dass Docker das aktuelle Verzeichnis als Root-Verzeichnis für den HTTP-Server nutzt. Außerdem liefere ich eine eigene ini-Datei für PHP mit. Wichtig ist außerdem die Verknüpfung zu meinem zuvor erstellen MySQL-Container über den Parameter –link. Der Rest wird analog des ersten Containers vorgegeben: Port, Name, Image, usw.
1 2 3 4 5 6 7 8 9 10 11 |
#!/bin/bash docker stop nickyreinert-de docker rm nickyreinert-de docker run \ --link mysql \ --name nickyreinert-de \ --volume ${PWD}/dev/wordpress.ini:/usr/local/etc/php/conf.d/uploads.ini \ --volume ${PWD}:/var/www/html \ --publish 80:80 \ --detach \ richarvey/nginx-php-fpm |
xdebug installieren
Leider liefert das nginx-Image kein xdebug mit. Bzw: Zurecht – der Sinn des ganzen Konzeptes ist es ja, schlanke Container nutzen zu können. Eine All-In-One-Lösung entspräche letztlich ja wieder einer kompletten virtuellen Maschine. Für mich jedenfalls heißt das, dass ich das nginx-Image nun irgendwie mit xdebug füttern muss. Das passiert mit docker build. Dazu benötige ich zunächst ein Dockerfile, dass auch genau so heißt und folgendermaßen aufgebaut ist – Erklärung folgt darunter:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
FROM richarvey/nginx-php-fpm RUN apk add --no-cache --virtual .phpize-deps $PHPIZE_DEPS RUN apk add --no-cache nano RUN pecl install xdebug RUN echo 'zend_extension = /usr/local/lib/php/extensions/no-debug-non-zts-20170718/xdebug.so' >> /usr/local/etc/php/php.ini RUN touch /usr/local/etc/php/conf.d/xdebug.ini; \ echo xdebug.remote_enable=1 >> /usr/local/etc/php/conf.d/xdebug.ini; \ echo xdebug.remote_autostart=1 >> /usr/local/etc/php/conf.d/xdebug.ini; \ echo xdebug.remote_connect_back=0 >> /usr/local/etc/php/conf.d/xdebug.ini; \ echo xdebug.remote_host=192.168.0.11 >> /usr/local/etc/php/conf.d/xdebug.ini; \ echo xdebug.remote_port=9000 >> /usr/local/etc/php/conf.d/xdebug.ini; \ echo xdebug.remote_log=/tmp/php-xdebug.log >> /usr/local/etc/php/conf.d/xdebug.ini; |
1 |
Cannot find autoconf. Please check your autoconf installation and the # $PHP_AUTOCONF environment variable. Then, rerun this script. |
1 |
RUN apk add --no-cache --virtual .phpize-deps $PHPIZE_DEPS |
1 |
W: Creating socket for '127.0.0.1:9000', poll success, but error: Operation in progress (29). |
1 |
docker build --tag nginx-php-fpm-xdebug . |
Visual Studio Code
Der Vollständigkeit halber möchte ich nun noch die Schritte dokumentieren, die bei Microsofts Visual Studio Code (VSC) notwendig sind. Hier installiert man zunächst das Paket PHP Debug. Im Debug-Bereich fügt man dann eine neue Konfiguration hinzu, die VSC mitteilt, unter welcher IP-Adresse xdebug erreichbar ist – nämlich 127.0.0.1 und dem üblichen Port: 9000:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
{ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "Listen for XDebug", "type": "php", "request": "launch", "port": 9000, "host": "127.0.0.1" } ] } |
