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:

Logo

               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
                      Dadurch wird ein Verzeichnis „laravel“ erstellt, das Sie nach Belieben umbenennen können.

               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
                     Erläuterungen:

                          -v ${pwd}:/app:     - „v“ steht für „volume“, „pwd“ steht für „current working directory“. Wir sagen Docker, dass es                                                             alle Docker-Composer-Bilder-Dateien im „app“-Verzeichnis installieren muss.                                                                                           Das Flag -v (für „volume“) wird verwendet, um Anwendungsdateien und                                                                                           Anwendungsverzeichnisse (hier das Laravel-Verzeichnis ‚app‘) in einem Docker-Behälter zu                                                             binden. Verschiedene Dateien und Verzeichnisse in einer Anwendung können in verschiedene                                                             Docker-Behälter eingehängt werden.

                         --rm:                         Damit wird der Docker-Behälter angewiesen, sich selbst zu entfernen ('--rm'), nachdem er seine                                                            Arbeit beendet hat. Docker-Composer-Bild wird nicht mehr benötigt.

                         Mehr zum Docker Composer-Bild

                         Mehr zu Docker Volumes

               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.

docker-compose.yaml:
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)

app.dockerfile
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
								

                     Unser zweites Dockerfile ist Nginx-‘web‘-Docker-Behälter web.dockerfile (Zeile 18 in der Datei                                                    docker-compose.yaml).

                     Es läuft:

                    - (Zeile 1 unten) nginx 1.27.2:      Das offizielle Docker-Bild des Reverse-Proxy-Servers Nginx.

                    - (Zeile 3 unten) vhost.conf:         Die Datei /docker/vhost.conf wird kopiert und überschreibt die Datei                                                                                           /etc/nginx/conf.d/default.conf, Nginx-Standarddatei.
                                                                          (Hinweis: vhost.conf wird weiter unten erklärt.)                    

                    - (Zeile 5 und 6 unten) stdout:       Wir erstellen einen Symlink zwischen (1) Nginx-Standardausgabe und                                                                                           (2) Nginx access.log-Datei sowie die Datei Nginx error.log.

web.dockerfile
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.

vhost.conf
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

Die Laravel .env Datei wurde in Schritt 4 (Erstellen einer docker-compose.yaml Datei) angedeutet, als es um den Inhalt des MySQL-Dienst und des PhpMyAdmin-Dienst (Zeile 31 und Zeile 41 in docker-compose.yaml).

Die bei der Installation des Laravel Composers erzeugte Standard .env.example muss in .env umbenannt werden und würde typischerweise folgendermaßen aussehen:

.env
DB_HOST=127.0.0.1
DB_DATABASE=docker-database
DB_USERNAME=docker-user
DB_PASSWORD=docker-password

MAIL_HOST=mailhog
MAIL_PORT=1025
								
Die beiden Dienste in der Datei docker-compose.yaml können die Werte der Variablen in der Datei .env lesen.

                  Schritt 7: Start der Docker-Behälter – Erstellung der Docker-Bilder

Wir führen den folgenden Befehl aus, um (1) Die Docker-Behälter zu starten  (2) Alle Docker-Bilder zu erstellen.

$ docker-compose up
                  (Im Grunde genommen eine Kombination aus dem docker-compose build and docker-compose run Befehle.)

                  Bevor wir die Index-Seite unserer Laravel-Anwendung aufrufen können, müssen wir noch zwei letzte Schritte durchführen:

                      1. Um die Sicherheits- und Verschlüsselungsfunktionen von Laravel zu erstellen, erzeugen wir eine neue                                         32-Zeichen-Zeichenkette APP_KEY Wert in der .env Datei.

                      2. Wir führen einen Laravel-Befehl aus, um eine kompilierte Datei der am häufigsten verwendeten Laravel-Klassen zu                           erstellen. Diese kompilierte Datei reduziert die Gesamtanzahl der Dateien, die von Laravel jedes Mal aufgerufen                           werden müssen, wenn eine Anfrage an den Server gestellt wird.

                 Wir benutzen docker-compose exec um die folgenden beiden Laravel-Befehle in unserer bestehenden und laufenden                  „app“ auszuführen Docker-Behälter:

$ docker-compose exec app php artisan key:generate

$ docker-compose exec app php artisan optimize
                 Wenn alles gut gegangen ist, sollten nun die folgenden drei URLs erreichbar sein:

                    http://localhost - Um unsere Laravel-Anwendungsindexseite anzuzeigen.

                    http://localhost:8888 - Um die phpMyAdmin Seite anzuzeigen.

                    http://localhost:8025 - Um MailHog UI anzuzeigen.

Kâmi Barut-Wanayo © 2024 - 2025