Docker bietet eine elegante Möglichkeit, Anwendungen mit mehreren Containern zu definieren und zu verwalten. In diesem Beitrag führe ich Sie durch die Docker Compose-Konfiguration, die die Entwicklungsumgebung für Willow CMS erstellt. Dieses Setup umfasst alles vom Anwendungsserver bis zu den Entwicklungstools, sodass Sie sofort mit der Entwicklung beginnen können. Den Code für Willow CMS erhalten Sie hier .
Über docker-compose.yml konfigurierte Kerndienste
WillowCMS-Anwendungsserver
Das Herzstück unseres Setups ist der WillowCMS -Dienst :
willowcms:
build:
context: .
dockerfile: docker/willowcms/Dockerfile
args:
- UID=${UID:-1000}
- GID=${GID:-1000}
ports:
- "8080:80"
volumes:
- .:/var/www/html/
- ./docker/willowcms/config/app/cms_app_local.php:/var/www/html/config/app_local.php
- ./logs/nginx:/var/log/nginx/
environment:
- REDIS_USERNAME=root
- REDIS_PASSWORD=root
Diese Konfiguration:
- Definiert einen Dienst namens willowcms
- Konfiguriert den Dienst als benutzerdefinierten Container aus unserem Dockerfile, der die Installation und Konfiguration der Containersoftware übernimmt
- Übergibt zwei benannte Argumente, UID (Benutzer-ID) und GID (Gruppen-ID), die verwendet werden, um ordnungsgemäße Dateiberechtigungen zwischen Host und Container sicherzustellen.
- Ordnet Port 8080 auf dem Host zu, um auf die Anwendung auf Port 80 des Containers zuzugreifen
- Ordnet das gesamte Projektverzeichnis (.) vom Host-Rechner zu
/var/www/html/
innerhalb des Containers. Auf diese Weise können Sie VS Code auf dem Host verwenden, um den Quellcode zu ändern und die daraus resultierenden Änderungen sofort auf dem Entwicklungsserver anzuzeigen, auf dem der Code gehostet wird. - Ordnet die Konfigurationsdatei cms_app_local.php vom Host dem Container zu (mit einem neuen Namen innerhalb des Containers). Dadurch können wir separate Konfigurationseinstellungen für die Entwicklung beibehalten, ohne das Risiko einzugehen, dass die App-Konfiguration in das Repo eingecheckt wird.
- Ordnet das Nginx-Protokollverzeichnis dem Host und dem Container zu, sodass wir Nginx-Protokolle direkt von Ihrem Hostcomputer aus anzeigen können, ohne den Container aufrufen zu müssen.
- Definiert 2 Umgebungsvariablen, die zum Konfigurieren des Redis-Dienstes verwendet werden
Sie können auf Ihrem Hostcomputer unter http://localhost:8080 auf Willow CMS zugreifen.
Ich werde später auf die Details des Dockerfiles eingehen. Für den Moment sollten Sie wissen, dass es für die Installation und Konfiguration von Nginx und PHP-FPM sowie anderer Software verantwortlich ist, die zum Ausführen von Willow CMS (und jeder anderen CakePHP-Anwendung) erforderlich ist.
Datenbankebene
Wir verwenden MySQL 8.4.3 als unsere Datenbank :
mysql:
image: mysql:8.4.3
environment:
MYSQL_ROOT_PASSWORD: password
ports:
- "3310:3306"
volumes:
- mysql_data:/var/lib/mysql
- ./docker/mysql/init.sql:/docker-entrypoint-initdb.d/init.sql
Diese Konfiguration:
- Definiert einen Dienst namens mysql. Dies ist wichtig und die anderen Container können
mysql
als Hostname für den MySQL-Dienst anstelle einer IP-Adresse. - Verwendet das offizielle Docker-Image von MySQL Server Community Edition v8.4.3 und konfiguriert die Umgebungsvariable, die zum Festlegen des Root-Passworts verwendet wird.
- Ordnet Port 3310 auf dem Hostcomputer 3306 auf dem Container zu.
- Montiert einen
mysql_data
Ordner, der von Docker verwaltet wird, in den Container, in dem MySQL alle seine Datenbankdateien speichert. Dies ermöglicht es uns, Daten über verschiedene Builds/Instanzen dieses Containers hinweg beizubehalten. - Kopiert ein Initialisierungs-SQL-Skript in die
docker-entrypoint-initdb.d/init.sql
Verzeichnis innerhalb des Containers. Dieses Verzeichnis ist vom MySQL-Image vorkonfiguriert, um alle darin enthaltenen Skripts automatisch auszuführen, wenn der Container zum ersten Mal initialisiert wird. Außerdem werden hier die Standard- und Testdatenbanken sowie die zugehörigen Benutzerkonten für die Entwicklungsumgebung erstellt.
Sie können auf Ihrem Hostcomputer unter http://localhost:3310 mithilfe von MySQL Workbench oder einer ähnlichen Anwendung wie phpMyAdmin auf MySQL zugreifen.
Entwicklungstools
phpMyAdmin
Zur Datenbankverwaltung binde ich phpMyAdmin ein:
phpmyadmin:
image: phpmyadmin
ports:
- 8082:80
environment:
- PMA_HOST=mysql
- PMA_USER=root
- PMA_PASSWORD=password
Sie sollten jetzt ein Muster erkennen, nämlich diese Konfiguration:
- Verwendet das offizielle, von der Community gepflegte Docker-Image für phpMyAdmin
- Ordnet Port 8082 auf dem Hostcomputer Port 80 auf dem Container zu.
- Konfiguriert die Umgebungsvariablen, die im Image verwendet werden, um den Standardhost, -benutzer und das Standardkennwort zu konfigurieren. Beachten Sie, dass der Host
mysql
der Name, den wir oben für den Datenbankdienst definiert haben.
Greifen Sie unter http://localhost:8082 auf phpMyAdmin zu, um eine benutzerfreundliche Datenbankverwaltungsoberfläche zu erhalten.
Jenkins CI/CD
Obwohl ich diesen Container derzeit in meinem Entwicklungsprozess nicht oft verwende, wird ein Continuous Integration-Dienst von Jenkins verwaltet :
jenkins:
build:
context: .
dockerfile: docker/jenkins/Dockerfile
privileged: true
user: root
ports:
- "8081:8080"
- "50000:50000"
volumes:
- jenkins_home:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
- ./docker/jenkins/jenkins.yaml:/var/jenkins_home/jenkins.yaml
environment:
- JAVA_OPTS=-Djenkins.install.runSetupWizard=false
Diese Konfiguration:
- Definiert einen Dienst namens Jenkins, der mithilfe einer Docker-Datei erstellt wurde. Wir tun dies, weil ich die Konfiguration als Code verwenden möchte, sodass Jenkins mit nützlichen Jobs und der erforderlichen Software vorkonfiguriert ist.
- Führt den Container mit erhöhten Berechtigungen (privileged: true) und als Root-Benutzer für vollständigen Systemzugriff aus.
- Ordnet Port 8081 auf dem Host dem Port 8080 der Jenkins-Weboberfläche des Containers zu und ordnet Port 50000 für die Jenkins-Agent-Kommunikation zu.
- Verwendet ein benanntes Volume „jenkins_home“, um alle Jenkins-Daten und -Konfigurationen beizubehalten.
- Mountet den Docker-Socket auf dem Host, um Jenkins beim Ausführen von Jobs das Erstellen und Verwalten von Docker-Containern zu ermöglichen.
- Bietet die Erstkonfiguration über jenkins.yaml unter Verwendung von Jenkins Configuration as Code.
- Überspringt den Jenkins-Setup-Assistent durch Festlegen der Umgebungsvariable JAVA_OPTS (Jenkins ist sofort einsatzbereit und kann sofort mit Jobs verwendet werden!).
Greifen Sie auf Jenkins unter http://localhost:8081 zu. In Zukunft wird Jenkins verwendet, um automatisierte Front-End-Tests in einem Browser auszuführen. Derzeit hat es die Aufgabe, die PHPUnit-Tests auf dem Hauptzweig auszuführen.
E-Mail-Tests mit Mailpit
Da wir zum Testen von E-Mails keine echten E-Mails in der Entwicklungsumgebung senden möchten, verwenden wir Mailpit , um E-Mails von Willow CMS zu erfassen:
mailpit:
image: axllent/mailpit:latest
ports:
- "1125:1025"
- "8025:8025"
volumes:
- mailpit_data:/data
environment:
- MP_MAX_MESSAGES=5000
- MP_DATABASE=/data/mailpit.db
- MP_SMTP_AUTH_ACCEPT_ANY=1
- MP_SMTP_AUTH_ALLOW_INSECURE=1
Diese Konfiguration:
- Erstellt einen Dienst namens
mailpit
. - Verwendet das neueste offizielle Mailpit-Docker-Image (axllent/mailpit:latest).
- Ordnet den Port 1125 auf dem Host dem SMTP-Port 1025 von Mailpit im Container zum Erfassen von E-Mails zu. Dadurch kann der Willowcms-Container, der den CakePHP-Code ausführt, E-Mails an mailpit:1025 senden.
- Ordnet Port 8025 auf dem Host dem Port 8025 der Mailpit-Weboberfläche auf dem Container zu.
Mailpit erfasst alle ausgehenden E-Mails und bietet unter http://localhost:8025 eine Weboberfläche zum Anzeigen dieser E-Mails.
Redis-Verwaltung
Redis Commander bietet eine Weboberfläche zur Redis-Verwaltung:
redis-commander:
image: rediscommander/redis-commander:latest
environment:
- REDIS_HOST=willowcms
- REDIS_PORT=6379
- REDIS_PASSWORD=root
- HTTP_USER=root
- HTTP_PASSWORD=root
ports:
- "8084:8081"
depends_on:
- willowcms
Diese Konfiguration:
- Verwendet das neueste Weboberflächen-Image von Redis Commander.
- Konfiguriert im Image verwendete Umgebungsvariablen, um standardmäßig eine Verbindung mit der Redis-Instanz herzustellen, die auf dem Dienst „willowcms“ auf Port 6379 mit dem Kennwort „root“ ausgeführt wird.
- Konfiguriert das Webinterface mit HTTP-Basisauthentifizierung (Benutzername: root, Passwort: root)
- Ordnet Port 8084 auf dem Host dem Port 8081 der Weboberfläche von Redis Commander zu.
- Stellt sicher, dass der Redis-Dienst (willowcms) vor Redis Commander gestartet wird.
Greifen Sie auf Redis Commander unter http://localhost:8084 zu, um die WillowCMS Redis-Instanz zu überwachen und zu verwalten. Es wird als Speicher für das CakePHP Queue Plugin verwendet.
Dauerhafter Speicher
Wir definieren drei Volumes für die Datenpersistenz :
volumes:
mysql_data:
rabbitmq_data:
jenkins_home:
Diese Volumes stellen sicher, dass unsere Daten Neustarts und Neuaufbauten des Containers überstehen, obwohl dies nicht erforderlich ist.
Zugriff auf die einzelnen Dienste
Sobald die Umgebung ausgeführt wird, finden Sie die einzelnen Dienste hier:
- WillowCMS: http://localhost:8080
- phpMyAdmin: http://localhost:8082
- Jenkins: http://localhost:8081
- MailHog: http://localhost:8025
- Redis Commander: http://localhost:8084
Starten der Umgebung
Um eine Docker-Umgebung zu starten, führen Sie normalerweise Folgendes aus:
docker-compose up -d
Dadurch werden alle Dienste im getrennten Modus erstellt und gestartet (d. h. Sie können weiterhin das Terminal verwenden, in das Sie den Befehl eingegeben haben), wobei die Standarddatei docker-compose.yml verwendet wird. Ich stelle jedoch ein praktisches Skript zur Verfügung, das Ihnen einige Optionen zum Starten/Stoppen der Docker-Entwicklungsumgebung bietet.
Führen Sie statt des obigen Befehls Folgendes aus:
./setup_dev_env.sh
Dieses Skript automatisiert die Verwaltung der Docker-Entwicklungsumgebung und die Einrichtung von Willow CMS. Folgendes macht es:
Zunächst wird das Betriebssystem erkannt, um festzustellen, obsudo
wird für Docker-Befehle benötigt (normalerweise unter Linux erforderlich, aber nicht unter macOS). Anschließend wird geprüft, ob die Docker-Container für das Projekt bereits ausgeführt werden, und wenn nicht, werden sie mit Docker Compose gestartet .
Sobald die Container laufen, wartet das Skript, bis der MySQL-Dienst bereit ist, indem es das Dienstprogramm „wait-for-it“ verwendet. Beachten Sie, dass das Skript auf dem Container ausgeführt wird, der denwillowcms
Service und nutzt diemysql
Hostname. Wenn ich die Host-Maschine und den Port (127.0.0.1:3310) verwende, würde ich beim Warten annehmen, dass MySQL läuft, da Docker auf diesem Host-Port lauscht, bevor MySQL Server möglicherweise begonnen hat, auf seinem Container-Port zu lauschen.
Nachdem MySQL verfügbar ist, installiert das Skript Projektabhängigkeiten mithilfe von Composer im Docker-Container.
Anschließend führt das Skript eine Prüfung durch, um festzustellen, ob die Datenbank zuvor eingerichtet wurde, indem es nach einer „Einstellungen“-Tabelle sucht. Diese Prüfung wird von einem benutzerdefinierten CakePHP-Befehl durchgeführt (mehr dazu in einem zukünftigen Blog-Beitrag). Wenn die Tabelle vorhanden ist (was auf eine vorherige Einrichtung hinweist), werden dem Benutzer folgende Optionen angezeigt :
- Alle Daten löschen und neu beginnen
- Container neu erstellen
- Starten Sie die Umgebung neu
- Mit dem aktuellen Setup fortfahren
Wenn es sich um eine Ersteinrichtung handelt (oder nach einer Datenlöschung), führt das Skript die ersten Einrichtungsaufgaben aus, darunter:
- Festlegen geeigneter Berechtigungen für wichtige Verzeichnisse
- Ausführen von Datenbankmigrationen
- Erstellen eines Standardadministratorbenutzers
- Standarddaten in die Datenbank importieren
Abschließend löscht das Skript, unabhängig davon, ob es sich um eine Erst- oder Folgeeinrichtung handelt, den Anwendungscache, bevor es abgeschlossen wird. Dadurch wird ein sauberer Zustand sichergestellt, bevor mit der Entwicklungsarbeit begonnen werden kann.
Deep Dive – Das Dockerfile von Willow CMS erklärt
Jetzt, da Sie auf dem Laufenden sind, werfen wir einen Blick auf die Docker-Datei, die zum Erstellen des Containers verwendet wird, der die Willow CMS-Codebasis hostet.
Basis-Image und Paketinstallation
Der Container startet mit Alpine Linux v3.20 , das aufgrund seines geringen Platzbedarfs und seiner Sicherheit ausgewählt wurde. Es installiert einen sorgfältig ausgewählten Satz von Paketen , darunter:
- Redis für Caching und Warteschlangenverwaltung
- Nginx als Webserver
- PHP 8.3 mit wichtigen Erweiterungen für CakePHP und Willow CMS
- Supervisor für Prozessmanagement
- ImageMagick zur Bildverarbeitung
- Entwicklungstools (curl, wget, unzip, bash)
Dienstkonfiguration
Das Dockerfile richtet mehrere Dienste ein:
- Redis-Konfiguration : Konfiguriert Redis mit Benutzernamen-/Passwortschutz und Localhost-Bindung. Hier wird die in docker-compose.yml konfigurierte Umgebung verwendet.
RUN echo "requirepass ${REDIS_PASSWORD}" >> /etc/redis.conf && \
echo "bind 127.0.0.1" >> /etc/redis.conf && \
echo "user ${REDIS_USERNAME} on >${REDIS_PASSWORD} ~* +@all" >> /etc/redis.conf
- Nginx-Setup : Kopiert zwei Konfigurationsdateien :
nginx.conf
für globale HTTP-Einstellungennginx-cms.conf
für den anwendungsspezifischen CakePHP- Serverblock
# Configure nginx - http
COPY docker/willowcms/config/nginx/nginx.conf /etc/nginx/nginx.conf
# Configure nginx - default server
COPY docker/willowcms/config/nginx/nginx-cms.conf /etc/nginx/conf.d/default.conf
- PHP-FPM-Konfiguration : Installiert benutzerdefinierte PHP-Konfigurationen:
fpm-pool.conf
für PHP-FPM-Prozessmanagementphp.ini
für PHP-Einstellungen optimiert für CakePHP
Zur einfacheren Wartung definieren wir eine Variable direkt im Dockerfile für diePHP_INI_DIR
wohin die Konfigurationsdateien gehen.
ENV PHP_INI_DIR /etc/php83
COPY docker/willowcms/config/php/fpm-pool.conf ${PHP_INI_DIR}/php-fpm.d/www.conf
COPY docker/willowcms/config/php/php.ini ${PHP_INI_DIR}/conf.d/custom.ini
- Composer-Installation : Installiert Composer für die PHP-Abhängigkeitsverwaltung. Wir möchten Composer nicht vom Hostcomputer im Quellcodeordner ausführen, der dann in den Container gemappt wird. Wir könnten, aber wir würden auf Datei-/Ordnerberechtigungsprobleme zwischen Host und Container stoßen, die Dinge wie die Cache-Generierung zu einer Qual machen. Vertrauen Sie mir, dies ist eine bessere Möglichkeit, dies zu tun, wenn Sie die Benutzer- und Gruppenberechtigungen basierend auf der Host-Benutzer-ID und der Gruppen-ID einrichten, die beim Ausführen von docker-compose.yml oder über setup_dev_env.sh festgelegt werden.
Berechtigungen
Das Dockerfile richtet einen Benutzer und eine Gruppe ein, die bei Host-/Containerberechtigungen helfen:
- Erstellt einen Nicht-Root-Benutzer (niemand) mit konfigurierbarer UID/GID, die vom Benutzer des Hostcomputers und seiner Gruppe übernommen wird.
- Legt die entsprechenden Eigentümerschaften für Webverzeichnisse fest.
- Wechselt für laufende Prozesse zum Nicht-Root-Benutzer.
- Konfiguriert die richtigen Verzeichnisberechtigungen für Nginx und PHP-FPM.
RUN deluser nobody && \
addgroup -g ${GID} -S nobody && \
adduser -u ${UID} -S -G nobody nobody
Prozessmanagement
Supervisord wird verwendet, um mehrere Prozesse innerhalb des Containers zu verwalten:
- Startet und überwacht Nginx
- Verwaltet PHP-FPM
- Verwaltet den Redis-Server
- Stellt sicher, dass alle Dienste in der richtigen Reihenfolge starten
Wir tun dies, indem wir die Supervisord-Konfiguration kopieren und den Befehl für den Start des Containers festlegen.
Gesundheitsüberwachung
Das Dockerfile enthält eine Integritätsprüfung, die den Status des Containers validiert, indem sie prüft, ob PHP-FPM antwortet. Dies ist eine nette Funktion, die aus der Produktionsversion dieser Docker-Umgebung hervorgegangen ist.
Abschluss
Diese Docker Compose-Konfiguration bietet eine vollständige Entwicklungsumgebung für Willow CMS. Durch die Containerisierung dieser Dienste stellen wir Konsistenz zwischen verschiedenen Host-Rechnern sicher und erleichtern neuen Entwicklern den Einstieg mit einer bekannten, funktionierenden Konfiguration. Egal, ob Sie an einer neuen Funktion arbeiten, E-Mail-Vorlagen testen oder die Datenbank ändern, alles ist nur eine Portnummer entfernt.