Docker für PHP-Entwickler: Grundkenntnisse
Wir möchten versuchen, eine lokale Windows-Docker-Umgebung für Laravel (neueste Version) einzurichten.
Da ich immer wieder auf Verzeichnisse, Unterverzeichnisse und Dateien mit Namen verweisen werde, bitte ich Sie,
das Folgende beizubehalten.
Baumstruktur der Dateien und Verzeichnisse:
In unserer Studie zu diesem dockerisierten Laravel-Setup werden wir die vier grundlegenden Komponenten von Docker
im
 
Detail betrachten:
1. Docker-Dienste
2. Docker Compose
3. Docker volumes
4. Docker-Umgebungsvariablen
Schritt 1: (Windows-Installation) Docker herunterladen und installieren
Alle Schritte
Schritt 2: Laravel herunterladen mit Git
1) Zuerst composer und git herunterladen und installieren (falls noch nicht geschehen):
Composer installieren
git installieren
2) Die neueste Version von Laravel klonen
 
git clone https://github.com/laravel/laravel.git
Schritt 3: Composer Docker-Bild installieren
Die Entwicklung unserer Laravel-Anwendung erfordert die Installation von „Dependencies“
durch Composer, um
 
bestimmte Funktionen des Frameworks zu nutzen.
Mit Docker Composer Image können wir einen Befehl ausführen, der (1) einen neuen Docker-Behälter erstellt,
(2)
Argumente an diesen Docker-Behälter übergibt und (3) sich selbst wieder entfernt,
nachdem er seine Arbeit erledigt
hat.
Der Befehl:
$ docker run --rm -v ${pwd}:/app composer install
Schritt 4: Erstellen einer Docker-Compose-Datei
Eine Docker-Compose-Datei ist die Datei, die zur Definition und Ausführung einer Multi-Docker-Behälter-Anwendung
verwendet wird.
In unserer Docker Compose YAML-Datei konfigurieren wir alle Anwendungsdienste, die unsere
Anwendung benötigt.
Bevor wir einen Blick auf docker-compose.yaml werfen, fragen wir:
Was sind Docker-Dienste?
In der Docker-Dokumentation heißt es: „Ein Dienst ist eine Einheit für die Bereitstellung, die definiert, welches
Docker-Behälter-Bild zu verwenden ist, welche
Befehle innerhalb des Docker-Behälters ausgeführt werden sollen, und
andere Optionen wie:
- Der Port, über den der Dienst erreichbar ist
- Das Netzwerk, über das der Dienst mit anderen Diensten verbunden ist
- Die CPU- und Speichergrenzen für den Dienst“
Für unsere gedockte Laravel-Installation werden wir die folgenden fünf Dienste einrichten:
1. PHP-FPM-Process-Manager* (Anwendungsschicht)
2. Nginx* (Webschicht)
3. MySQL* (Datenbankschicht)
4. Mailhog** (Mailingschicht)
5. PhpMyAdmin** (Datenbankverwaltungsschicht)
* erforderlich
** optional
Strategie:
Die vollständige Datei docker-compose.yaml finden Sie unten.
Damit der Code auch wirklich Sinn macht, habe ich unten eine Reihe von Anmerkungen zur Erläuterung eingefügt, die
sich auf Zeilennummern im Code beziehen.
version: '3.8'
services:
# PHP-FPM-Prozessmanager-Dienstkonfiguration (Anwendungsschicht)
app:
build:
context: ./docker
dockerfile: app.dockerfile
working_dir: /var/www
volumes:
- ./:/var/www
depends_on:
- "database"
# Nginx-Webserver-Dienst-Konfiguration (Webschicht)
web:
build:
context: ./docker
dockerfile: web.dockerfile
working_dir: /var/www
volumes:
- ./:/var/www
depends_on:
- "app"
ports:
- 80:80
# MySQL-Dienstkonfiguration (Datenbankschicht)
database:
image: mysql:9.1.0
volumes:
- dbdata:/var/lib/mysql
environment:
MYSQL_DATABASE: ${DB_DATABASE}
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_USER: ${DB_USERNAME}
ports:
- 33061:3306
# PhpMyAdmin-Dienstkonfiguration (Datenbankverwaltung)
pma:
image: phpmyadmin:5.2.1
environment:
- PMA_ARBITRARY=1
- PMA_HOST=${DB_HOST}
- PMA_USER=${DB_USERNAME}
- PMA_PASSWORD=${DB_PASSWORD}
- PMA_PORT=${DB_PORT}
depends_on:
- database
ports:
- 8888:80
# Mailhog Server-Dienst-Konfiguration (Mailing-Schicht)
mailhog:
image: mailhog/mailhog
logging:
driver: 'none'
ports:
- 1025:1025
- 8025:8025
volumes:
dbdata:
Allgemein
(Zeile 1) Version:
Die verwendete Version von Docker Compose (hier 3.8).
Docker Swarm
kann nur mit
Docker Compose verwendet werden (d. h. Docker Compose Version 3 und nicht Version 2).
(Zeile 2) Dienste:
Instanzen von Docker-Bildern, d. h. unsere fünf Dienste, werden hier aufgeführt.
PHP-FPM Prozessmanager-Dienst
Wir verwenden PHP-FPM als Anwendungsschicht für unseren Webserver Nginx, um PHP-Client-Anfragen
bearbeiten zu können und Anwendungscode zu bearbeiten.
 
Als Webserver kann Apache anstelle von Nginx verwendet werden. Nginx ist jedoch insgesamt besser im
Umgang
mit statischen Inhalten und hohem Verkehrsaufkommen.
 
Wir werden uns die Konfiguration des PHP-FPM app.dockerfile-Docker-Bilds später ansehen. Es ruft die GD-Image
Processing-Bibliothek und Imagick-Image-Processing-Library.
(Zeile 6) build:
Ermöglicht es Docker Compose, zu wissen, auf welchen Satz von Dateien der Build zugreifen
soll.
(Zeile 7) context:
Der relative Pfad zu unserer Dockerfile: app.dockerfile. In unserem Fall befindet sich
app.dockerfile im Docker-Verzeichnis.
(Zeile 8) dockerfile:
app.dockerfile wird im Folgenden erörtert.
(Zeile 9) working_dir:
Das Verzeichnis, in dem der Docker-Behälter PHP-FPM Process Manager arbeitet, führt
Aufgaben aus.
(line 10) volumes:
Der Docker-Behälter (hier das Verzeichnis '/var/www'), in den wir das Verzeichnis mounten, in
dem unsere Datei docker-compose.yaml befindet. Der Webserver weiß also, wo er nach der
Datei Anwendungsdateien findet, die für die Ausführung der Anwendung benötigt werden.
(Zeile 12) depends_on:
Stellt sicher, dass ein anderer Dienst (hier die Datenbank Docker-Behälter) vor dem
Anwendungscontainer startet.
Nginx Dienst.
Aus den bereits erwähnten Gründen haben wir uns für Nginx und nicht für Apache als Webserver entschieden.
(Zeile 16) build:
Startzeile für diesen Dienst, die Docker Compose den Speicherort der Dockerdatei mitteilt,
relativ zu docker-compose.yaml.
(Zeile 17) context:
Sie verweist auf web.dockerfile, die erforderliche Dockerdatei für diesen Dienst.
Wir werden
später eine Datei betrachten, die von web.dockerfile aufgerufen wird: vhost.conf.
Diese
virtuelle Hostdatei ermöglicht Nginx-Websites auf einem einzigen Server.
(Zeile 18) dockerfile:
web.dockerfile wird im Folgenden beschrieben.
(Zeile 19) working_dir:
Das Verzeichnis, in dem der Nginx-Behälter arbeitet und Aufgaben ausführt
.
(Zeile 20) volumes:
Der Docker-Behälter (hier das Verzeichnis '/var/www'), in dem wir das Verzeichnis
mounten, in dem unsere docker-compose.yaml Datei befindet. Die Dateien, die Nginx zum
ordnungsgemäßen Betrieb benötigt, befinden sich in diesem Verzeichnis.
(Zeile 22) depends_on:
Der Nginx-Server benötigt den PHP-FPM-Prozessmanagerdienst, um mit mehreren
gleichzeitigen Kundenanfragen, zum Beispiel.
(Zeile 24) ports:
Wir legen fest, welchen Port unser Docker-Behälter nach außen hin offenlegt und an
welchen Docker-Behälter interner Port, dem dieser externe Port zugeordnet ist.
Die Ports
werden nach der folgenden Konvention benannt:
[externer Port]:[interner Port].
MySQL-Dienst
Der MySQL-Dienst fungiert als Datenbankschicht und trennt die Befehle des PHP-Codes der Anwendung
von
Abfragen an die Datenbank.
(Zeile 28) image:
Anders als der PHP-FPM-Dienst und der Nginx-Dienst soll der MySQL-Dienst das
Docker-Bild
direkt von
Docker Hub Container Image Library
erhalten.
Je nach Anwendung
wählen wir die Version des MySQL-Tags, die wir verwenden müssen.
(Zeile 29) volumes:
Wir verwenden das benannte Volume dbdata (im Gegensatz zu den anonymen Volumes,
für PHP-FPM und Nginx verwendet werden), um die Dateien nach dem Anhalten
der Docker-Behälter aufrechtzuerhalten. Der Docker-Behälter kann jederzeit neu gestartet
werden und die Datenbank wird automatisch in ihren vorherigen Zustand zurückversetzt.
(Zeile 31) environment:
Die aufgelisteten „Schlüssel-Wert“-Paare fungieren als Umgebungsvariablen, die es dem
Docker-Behälter mit der MySQL-Datenbank kommunizieren. ${DB_DATABASE},
${DB_PASSWORD}, und ${DB_USERNAME} sind nur Aliasnamen. docker-composer.yaml sucht
nach einer Standardprojektonfigurationsdatei mit diesen Parametern im
 
Kontextverzeichnis, d. h. im Projektstamm-Verzeichnis in unserem Fall. Für Laravel ist diese
 
Konfigurationsdatei, .env.example, die werden wir .env umbenennen.
(Zeile 36) ports:
Ähnlich wie beim Nginx-Dienst ordnen wir dem externen Port 33601 der
 
MySQL-Docker-Behälter seinen internen Anschluss 3306.
Mailhog: Entwicklung Mailing Server Dienst
Laravel bietet API-basierte Treiber, die das Senden und Empfangen von E-Mails ermöglichen.
Unter den verschiedenen Docker-Tools zum Testen von E-Mails (Minio, Mailpit) haben wir Mailhog wegen
seiner
Portabilität, seiner Einfachheit und seiner Konfiguration ausgewählt.
(Zeile 53) image:
Wir folgen dem generischen Docker-Befehl:
docker image tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
um ein Docker-Bild zu erstellen, das in einem öffentlichen Repository liegt, und es für
Mailhog anzupassen.
(Zeile 54) logging:
Standardmäßig speichert Mailhog Protokolle in logs/mailhog.log.
Da sie eine Menge Platz
in Anspruch nehmen Ressourcen, setzen wir den Mailhog-Protokolltreiber auf ‚keine‘.
(Zeile 56) ports:
Die erste Gruppe von Ports (1025:1025) wird von der webbasierten Benutzeroberfläche
verwendet.
Die zweite Gruppe von Ports (8025:8025) wird vom SMTP-Server verwendet.
PhpMyAdmin-Dienst
PhpMyAdmin
kann als GUI-Schnittstelle zur Verwaltung von Datenbanken und Tabellen verwendet werden.
(Zeile 40) image:
Wir bauen das phpmyadmin:5.2.1-Bild aus dem offiziellen
Docker-Hub-Repository.
(Zeile 41) environment:
Wie beim MySQL-Dienst zuvor, holen wir uns die Umgebungsvariablen aus der Laravel
.env Datei. So können wir uns mit PhpMyAdmin verbinden, ohne
Authentifizierungsdaten eingeben zu müssen jedes Mal.
(Zeile 47) depends_on:
Damit PhpMyAdmin verwendet werden kann, muss der MySQL-Server
laufen. PhpMyAdmin als Dienst ist daher auf den Datenbank Behälter angewiesen.
(Zeile 49) ports:
Dieser Docker-Behälter-Port 8888 stellt eine Verbindung zu unserem Web-Interface
her, und der Docker-Behälter-Server lauscht zum MySQL-Server an Port 80.
Schritt 5: Kodierung der beiden Dockerdateien
Ein Dockerfile legt fest, wie Docker ein Docker-Bild erstellen soll.
Eine Docker Compose-Datei wird verwendet, um Docker mitzuteilen, wie Docker-Behälter ausgeführt
werden sollen.
Unser erstes Dockerfile ist der PHP-FPM „app“ Behälter app.dockerfile (Zeile 8 oben).
Es läuft:
- (Zeile 1 unten) Der PHP-FPM-Prozessor
- (Zeile 9 unten) Die GD-Image-Verarbeitungsbibliothek
- (Zeile 10 unten) pdo_mysql: Der Treiber, der den Zugriff auf MySQL-Datenbanken von PHP aus
über PHP Data Object (PDO)
FROM php:8.0-fpm
RUN apt-get update && apt-get install -y \
libfreetype6-dev \
libjpeg-dev \
libpng-dev \
libwebp-dev \
--no-install-recommends \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install pdo_mysql -j$(nproc) gd
FROM nginx:1.27.2
COPY vhost.conf /etc/nginx/conf.d/default.conf
RUN ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log
Die vhost.conf Datei
Die Datei vhost.conf bietet einen Mechanismus als virtuellen Host, um mehr als eine Website auf
einem System oder
einem Webserver wie Nginx oder Apache zu ermöglichen.
Ich habe einige Kommentare zur vhost.conf Konfiguration direkt in den Code unten eingefügt.
server {
listen 80; # Zwingt den Nginx-Webserver, auf Port 80 zu lauschen
index index.php index.html; # Die Indexdatei unseres Webservers ist entweder index.php oder index.html
root /var/www/public; # Stammverzeichnis des Nginx-Servers
location / {
try_files $uri /index.php?$args;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000; # Wobei der PHP-FPM-Dienst „app“ das CGI-Skript, in unserem Fall PHP, ausführt.
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
Schritt 6: Laravel-.env-Datei konfigurieren
DB_HOST=127.0.0.1
DB_DATABASE=docker-database
DB_USERNAME=docker-user
DB_PASSWORD=docker-password
MAIL_HOST=mailhog
MAIL_PORT=1025
Schritt 7: Start der Docker-Behälter – Erstellung der Docker-Bilder
$ docker-compose up
$ docker-compose exec app php artisan key:generate
$ docker-compose exec app php artisan optimize