Im dem folgenden Post möchte ich euch zeigen, wie ihr euch mit Hilfe von Docker Containern eine lokale PHP Entwicklungsumgebung erstellen könnt. Diese beinhaltet PHP FPM mit einen ganz einfachen Nginx Setup, sowie einer MySQL Datenbank.
Vorraussetzungen
Um die folgenden Schritte ausführen zu können, müssen docker
und docker-compose
installiert werden.
Ich setze den Umgang mit der Shell und Skript Dateien, sowie der hosts Datei voraus.
PHP im Container ausführen
Erstellt in einem neuen Projekt die Datei: docker-compose.yml
Als Inhalt nehmen wir zunächst eine minimale Konfiguration für einen PHP Container.
version: '3'
services:
php:
image: php
Öffnet jetzt eine Shell und stellt sicher, dass keine Docker Prozesse laufen.
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Im Root Verzeichnis unseres Projekts starten wir jetzt unseren Container.
docker-compose up
Solltet ihr den PHP Container vorher noch nie geladen haben, wird dieser zunächst heruntergeladen. Danach wird der Container gestartet.
Führt ihr jetzt jedoch wieder docker ps
aus, werdet ihr feststellen, dass der Container nicht mehr läuft. Das liegt daran, dass Docker nicht automatisch eine interaktive Shell startet. Wir müssten also ein Kommando ausführen, welches den Prozess offen hält. Nehmen wir dafür beispielsweise ein einfaches tail
.
version: '3'
services:
php:
image: php
command: tail -f /dev/null
Führen wir jetzt docker-compose up
aus, sehen wir, dass der Shell Prozess offen bleibt. Diesen können wir mit Strg + C
beenden. Damit wir in der selben Shell weiter arbeiten können, starten wir den Container als Daemon docker-compose up -d
. Falls ihr den Shell Output einsehen wollt, könnt Ihr docker-compose logs -f
benutzen.
Per docker ps
sehen wir, dass der PHP Container jetzt dauerhaft läuft. Das gibt und die Möglichkeit eine interaktive Shell für den Container zu öffnen.
docker-composer exec php bash
php
ist hierbei der Key den wir in der docker-compose.yml
vergeben haben.
In dem Container können wir jetzt PHP Kommandos ausführen.
php -v
php -r "echo 'Hello World' . PHP_EOL;"
PHP FPM mit Nginx Container verbinden
Da wir später Inhalte über einen Webserver ausliefern wollen, ändern wir unseren PHP Container zu einer FPM Version. Die verschiedenen Versionen könne auf Dockhub eingesehen werden.
version: '3'
services:
php:
image: php:7-fpm
Das Kommando um den Prozess am Leben zu erhalten benötigen wir jetzt nicht mehr. Das FPM Image startet initial den PHP FPM Prozess.
Ein kurzer Test zeigt das der Container selbständig läuft.
docker-compose down
docker-compose up -d
docker ps
Jetzt erweitern wir die docker-compose.yml
um den Nginx Teil.
version: '3'
services:
php:
image: php:7-fpm
volumes:
- ./src:/var/www/test
nginx:
image: nginx
volumes:
- ./config/mysite.conf.tpl:/etc/nginx/conf.d/mysite.conf.tpl
- ./src:/var/www/test
ports:
- 8080:80
environment:
- NGINX_HOST=test.local
- NGINX_PORT=80
- NGINX_ROOT=/var/www/test
command: >
/bin/bash -c "envsubst \
'\$$NGINX_HOST $$NGINX_PORT $$NGINX_ROOT'\
< /etc/nginx/conf.d/mysite.conf.tpl\
> /etc/nginx/conf.d/default.conf\
&& nginx -g 'daemon off;'"
Gehen wir die einzelnen Abschnitte nochmal durch.
image: nginx
Läd das nginx
Image von Dockerhub.
volumes:
- ./config/mysite.conf.tpl:/etc/nginx/conf.d/mysite.conf.tpl
- ./src:/var/www/test
Hier wird zunächst das Nginx Config Template aus dem Ordner ./config
in den Container eingebunden. Zum Erstellen dieser Datei kommen wir gleich. Genauso wird der Ordner ./src
hinzugefügt (Hier legen wir später die PHP Projekt Dateien ab)
Beachtet auch, dass der PHP Container die Projekt Dateien einbinden muss.
php
...
volumes:
- ./src:/var/www/test
Weiter mit dem Nginx Container
ports:
- 8080:80
Hiermit leiten wir den Container Port 80 auf unseren lokalen Port 8080 weiter.
environment:
- NGINX_HOST=test.local
- NGINX_PORT=80
- NGINX_ROOT=/var/www/test
Hier legen wir Environment Variablen fest, welche später im Nginx Config Template eingesetzt werden.
Ihr seht hier auch, dass ich die Domain test.local
verwende. Sollte Ihr die selbe Domain verwenden muss diese in eure hosts
Datei eingetragen werden.
command: >
/bin/bash -c "envsubst \
'\$$NGINX_HOST $$NGINX_PORT $$NGINX_ROOT'\
< /etc/nginx/conf.d/mysite.conf.tpl\
> /etc/nginx/conf.d/default.conf\
&& nginx -g 'daemon off;'"
Das ist das initiale Kommando für den Nginx Container. Es wird das Config Template mit den Environment Variablen ersetzt und der Nginx Server gestartet.
Nginx Config Template
Wie bereits erwähnt, sollte dieser File in einem Unterverzeichnis erstellt werden ./config/mysite.conf.tpl
server {
listen ${NGINX_PORT};
root ${NGINX_ROOT};
index index.php;
server_name ${NGINX_HOST};
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
}
}
Hier haben wir eine ganz simple Konfiguration für PHP FPM. Die Domain, der Port und das Verzeichnis werden aus den Docker Compose Variablen übergeben.
Interessant ist vielleicht das fastcgi_pass php:9000
. Hier wird der Nginx mit dem FPM verbunden. Die Domain des PHP Containers ist in dem Nginx Container automatisch unter Key Name php
.
PHP Datei erstellen
Um das ganze sinnvoll zu testen erstellen wir noch eine ./src/index.php
.
<?php
phpinfo();
Starten wir den Container docker-compose up -d
, können wir über ein Browser das Skript laden (http://test.local:8080/index.php)
Pass die Container deinen Bedürfnissen an
Standardmäßig hat der php:7-fpm
Container keine PHP Extensions installiert. Wollten wir z.B. pdo
benutzen, müssen wir den Container anpassen. Auf die gleiche Art und Weise könnt ihr beliebige andere installieren.
PHP Image durch eignen Build ersetzten.
In unserem Projekt erstellen wir ein neues Verzeichnis ./images
. Dort können wir für jeden Container, den wir anpassen, wollen einen Ordner mit einem Dockerfile erstellen. Zum Beispiel ./images/php/Dockerfile
Als Inhalt des Dockerfiles nehmen wir hier:
FROM php:7-fpm
RUN docker-php-ext-install pdo pdo_mysql
EXPOSE 9000
CMD ["php-fpm"]
Wir erweitern also das PHP FPM Image
FROM php:7-fpm
und fügen die Extension hinzu.
RUN docker-php-ext-install pdo pdo_mysql
Hier könntet ihr jetzt weitere Software installieren.
RUN apt update && apt install -y htop
Der Port 9000 muss weiterhin für den FPM exposed werden und das initiale Kommando bleibt das starten des FPM Prozesses.
EXPOSE 9000
CMD ["php-fpm"]
Zu guter Letzt, ersetzten wir in der docker-compose.yml
das image: php:7-fpm
durch den Pfad zu unserem Build build: images/php
version: '3'
services:
php:
build: images/php
volumes:
- ./src:/var/www/test
...
Nach der Änderung müsst ihr docker-compose build
ausführen. Nach diesem Prinzip könnt ihr auch andere Images anpassen. Wenn ihr nicht wisst, welches EXPOSE
oder CMD
ihr braucht, checkt einfach den Dockerfiles des Images, welches ihr erweitert.
MySQL Container hinzufügen
Jetzt erweitern wir die docker-compose.yml
um einen MySQL Container.
version: '3'
services:
php:
build: images/php
volumes:
- ./src:/var/www/test
nginx:
image: nginx
volumes:
- ./config/mysite.conf.tpl:/etc/nginx/conf.d/mysite.conf.tpl
- ./src:/var/www/test
ports:
- 8080:80
environment:
- NGINX_HOST=test.local
- NGINX_PORT=80
- NGINX_ROOT=/var/www/test
command: >
/bin/bash -c "envsubst \
'\$$NGINX_HOST $$NGINX_PORT $$NGINX_ROOT'\
< /etc/nginx/conf.d/mysite.conf.tpl\
> /etc/nginx/conf.d/default.conf\
&& nginx -g 'daemon off;'"
mysql:
image: mysql:5
volumes:
- mysql-data-vol:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: root
volumes:
mysql-data-vol:
image: mysql:5
Läd das MySQL Image von Dockerhub
volumes:
- mysql-data-vol:/var/lib/mysql
Hier weisen wir dem Container Pfaf /var/lib/mysql
ein Volume zu, welches wir am Ende der docker-compose.yml
erstellt haben. Dies sorgt dafür, dass die Daten der Datenbank persistent bleiben wenn wir den Container neustarten.
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: root
Über die Environment Variablen legen die Zugangsdaten fest.
Um die Verbindung zu testen könnt Ihr die index.php
verwenden.
<?php
try {
new PDO('mysql:host=mysql', 'root', 'root');
echo "connected";
} catch (\Exception $e) {
var_dump($e);
}
Hier gilt auch wieder das oben beschriebene Prinzip, dass die Domain des MySQL Containers der Key mysql
ist, welchen wir in der docker-compose.yml
vergeben haben.
Um den Zugriff auf die MySQL zu vereinfachen, könnt ihr auch hier den Port forwarden.
ports:
- 3306:3306
Wie geht es weiter?
Wenn ihr das Setup zum laufen bekommen habt und die Grundlagen versteht, könnt ihr das Setup beliebig erweitern.
Versucht andere Datenbanken oder Services anzubinden. Benutzt komplexere Konfigurationen um PHP Frameworks uvm. zum laufen zu bringen.
Hallo @eshad89, herzlich willkommen auf Steemit.
Wenn Du Fragen zu Steemit hast, oder Dich mit anderen „Steemians“ austauschen magst, schau einfach mal auf unserem Discord-Chat unter https://discord.gg/g6ktN45 vorbei. Mehr Informationen über den deutschsprachigen Discord-Chat findest Du in diesem Beitrag.
Wenn Du auf Deutsch schreibst, verwende immer #deutsch als einen der 5 Hashtags, um Deine Reichweite zu erhöhen.
Unter dem folgenden Link findest Du einige Anleitungen, die Dir den Einstieg in das Steem-Universum deutlich erleichtern werden: Deutschsprachige Tutorials für Steemit-Neulinge: Ein Überblick
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit