In diesem Beitrag bauen wir einen Web Application Stack mit Docker-Containern, bestehend aus Apache, MySQL, PHP (inkl. Redis) und PhpMyAdmin. Jeder Service läuft in einem eigenen Container. Auf diese Weise ist der Stack modular mit weiteren Diensten erweiterbar. Mit wenigen Handgriffen kann z.B. MySQL gegen PostgreSQL oder PHP 7.4 gegen eine andere Version getauscht werden. SSL und XDdebug sind bereits vorkonfiguriert. Der Stack kann somit für Development oder App Deployment benutzt werden.
Damit alles schön zusammen passt und wir möglichst wenig Aufwand haben, basiert alles auf den Docker Images von Bitnami.
Für unser Projekt benötigen wir die folgende Verzeichnisstruktur:
Der Unterordner “Build” ist nur für Geräte mit Apple Silicon relevant. Dazu später mehr.
Da alle Container über Docker Compose gestartet werden, erstellen wir zuerst die docker-compose.yml-Datei im Ordner “dstack”, neben dem Unterordner “docker”:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
--- # AMPP 1.0.9 # # Runs Apache, MySQL, PHP (+Redis) and PhpMyAdmin # SSL is preconfigured. # Imagemagick and XDebug are activated. # # Run with # docker-compose up -d # # (C)2020-2022 Harald Schneider # version: "3" services: # --- MySQL 5.7 # mysql: container_name: "ampp-mysql" image: bitnami/mysql:5.7 build: ./build/mysql restart: unless-stopped environment: - MYSQL_ROOT_PASSWORD=__YOUR_PASSWORD_HERE__ - MYSQL_USER=admin - MYSQL_PASSWORD=__YOUR_PASSWORD_HERE__ ports: - '3306:3306' volumes: - ./docker/mysql/data:/bitnami/mysql/data - ./docker/mysql/backup:/backup # --- PHP 7.4 # php: container_name: "ampp-php" image: bitnami/php-fpm:7.4 restart: unless-stopped depends_on: - redis volumes: #- /Users/hschneider/Work/Web:/app:delegated - ./docker/www:/app:delegated - ./docker/php/php.ini:/opt/bitnami/php/etc/conf.d/php.ini:ro # --- Apache 2.4 # apache: container_name: "ampp-apache" image: bitnami/apache:2.4 build: ./build/apache ports: - '80:8080' - '443:8443' depends_on: - php volumes: #- /Users/hschneider/Work/Web:/app:delegated - ./docker/www:/app:delegated - ./docker/apache/my_vhost.conf:/vhosts/myapp.conf:ro - ./docker/apache/certs:/certs # Use this for bitnami's builtin certs: # ./docker/apache/certs:/opt/bitnami/apache2/conf/bitnami/certs # --- Redis 6.0 # redis: container_name: "ampp-redis" image: bitnami/redis:6.0 restart: unless-stopped environment: - REDIS_PASSWORD=at15jx13 # --- PhpMyAdmin latest # Acccess via # http://127.0.0.1:8180 or https://127.0.0.1:8143 # Login with user root and mysql-password. # phpmyadmin: container_name: "ampp-phpmyadmin" image: bitnami/phpmyadmin:latest build: ./build/phpmyadmin depends_on: - mysql ports: - '8180:8080' - '8143:8443' environment: - DATABASE_HOST=host.docker.internal volumes: ampp-mysql: driver: local |
Außer PhpMyAdmin benutzen alle Dienste ihre Standard-Ports. Alle wichtigen Daten werden in persistenten Ordnern ausserhalb der Container gespeichert (Volumes).
Apache
Zuerst generieren wir mit dem folgenden Befehl ein selbst signiertes SSL-Zertifikat und speichern dessen Dateien im Ordner ./docker/apache/certs:
1 |
openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout server.key -out server.crt -subj "/CN=dstack.local" -days 3650 |
Für die Apache-Konfiguration legen wir folgende Datei an: ./docker/apache/my_vhost.conf:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://php:9000/app/$1 DirectoryIndex disabled DirectoryIndex index.php index.html <VirtualHost *:8080> DocumentRoot "/app" <Directory "/app"> Options -Indexes AllowOverride All Require all granted </Directory> </VirtualHost> # Create self signed certs with # openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout server.key -out server.crt -subj "/CN=YOURDOMAIN.LOCAL" -days 3650 # <VirtualHost *:8443> SSLEngine on SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL SSLCertificateFile "/certs/server.crt" SSLCertificateKeyFile "/certs/server.key" <Directory "/app"> Options -Indexes AllowOverride All Require all granted </Directory> </VirtualHost> |
Für unsere Website-Daten legen wir noch den Ordner ./docker/www an. In unserem Beispiel liegt hier die Datei info.php mit folgendem Inhalt:
1 2 3 |
<?php phpinfo(); ?> |
Damit ist Apache samt SSL komplett.
MySQL
Für MySQL benötigen wir nur einen leeren Ordner namens ./docker/mysql/data. Nach dem Start des MySQL-Containers, werden in diesem Ordner die Daten des MySQL-Servers erzeugt.
Bei Bedarf kann dieser Container noch mit einer Backup-Lösung für MySQL-Datenbanken, wie hier beschrieben, ergänzt werden.
PHP
Für die PHP-Konfiguration erzeugen wir die folgende Datei in ./docker/php/php.ini:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
display_errors = On expose_php = off max_execution_time = 360 max_input_time = 360 memory_limit = 256M upload_max_filesize = 1G post_max_size = 1G opcache.enable = 1 opcache.revalidate_freq = 2 opcache.validate_timestamps = 1 opcache.interned_strings_buffer = 32 opcache.memory_consumption = 256 extension=imagick.so zend_extension = "/opt/bitnami/php/lib/php/extensions/xdebug.so" [Xdebug] xdebug.remote_autostart=1 xdebug.remote_enable=1 xdebug.default_enable=0 xdebug.remote_host=host.docker.internal xdebug.remote_port=9000 xdebug.remote_connect_back=0 xdebug.profiler_enable=0 xdebug.remote_log="/tmp/xdebug.log" |
Unter Anderem werden hier die ImageMagick extension aktiviert und XDebug konfiguriert. PHP ist damit ebenfalls komplett.
PhpMyAdmin
PhpMyAdmin benötigt keine extra Konfiguration und ist später über die Adresse 127.0.0.1:81 oder :8143 (SSL) erreichbar. Die Anmeldung geschieht mit Benutzer “root” und dem MySQL Root User Passwort.
Alle Docker-Container auf einmal starten
Der folgende Befehlt starten nun alle Container auf einmal:
1 |
docker-compose up -d |
Zum Test geben wir im Browser http://127.0.0.1/info.php ein. Wenn wir alles richtig gemacht haben, erscheint nun die PHP-Info Page.
Docker: Zugriff von PHP auf MySQL liefert “Connection refused”
Hier ist folgende Besonderheit zu beachten:
Da ja alle Dienste in getrennten Docker-Containern laufen, wird ein Aufbau des DBConnects mit
1 |
'host' => '127.0.0.1:3306' |
nicht funktionieren. Statt dessen ist der Docker-Containername als Hostname zu verwenden:
1 |
'host' => 'mysql:3306' |
Solltet Ihr in docker-compose.yaml Port 3306 auf eine andere Portnummer gemapped haben, bleibt es in diesem Fall trotzdem bei 3306, da aus Perspektive des Webservers der interne Port des Containers sichtbar ist.
Nur für Apps, die von außen auf MySQL zugreifen (z.B. SequelPro, Querious, Navicat etc), wäre dann der gemappte Port gültig.
Docker: Bitnami Images auf Macs mit Apple Silicon lauffähig machen
Damit unser Docker Stack auch auf Macs mit Apple Silicon läuft, sind Build Patches für die Apache und PhpMyAdmin Docker Images notwendig. Dazu gehen wir wie folgt vor:
In der docker-compose.yml ergänzen wir die beiden markierten Zeilen:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# --- Apache 2.4 # apache: container_name: "ampp-apache" image: bitnami/apache:2.4 build: ./build/apache ... # --- PhpMyAdmin latest # Acccess via # http://127.0.0.1:8180 or https://127.0.0.1:8143 # Login with user root and mysql-password. # phpmyadmin: container_name: "ampp-phpmyadmin" image: bitnami/phpmyadmin:latest build: ./build/phpmyadmin ... |
Im Ordner “build” legen wir 2 weitere Ordner an:
“apache” mit einer Datei namens “Dockerfile”. Diese hat folgenden Inhalt:
1 2 3 4 |
FROM bitnami/apache:2.4 USER 0 RUN echo 'Mutex posixsem' >>/opt/bitnami/apache2/conf/httpd.conf USER 1001 |
Sowie den Ordner “phpmyadmin” mit ebenfalls einer Datei namens “Dockerfile” und folgenden Inhalt:
1 2 3 4 |
FROM bitnami/phpmyadmin:latest USER 0 RUN echo 'Mutex posixsem' >>/opt/bitnami/apache2/conf/httpd.conf USER 1001 |
Danach starten beide Docker Container auch auf Apple Silicon.
Viel Spaß beim dockern :-)
Hallo.
Auch ich mache meine ersten Gehversuche mit Docker. Ich habe alles aus diesem Tutorial nachgemacht und habe alle 5 Container zum Laufen bekommen unter Docker.
Allerdings funktionieren die URLs nicht, ich bekomme weder die “info.php” zum laufen noch komme ich in die “phpmyadmin” rein…
Was soll ich von der Konfiguration zeigen, damit man mir bei der Fehlersuche helfen kann?
Lg & Danke schon mal im Voraus
Kighlander
Welche URLs verwendest Du zum Aufruf?
Vielen Dank für das super Tutorial, genau sowas hatte ich gesucht.
Leider bekomme ich gleich nach “docker-compose up -d” einen ERROR das ein Pfad nicht
existiert. Ich habe die benötigte Verzeichnisstruktur wie im Bild oben übernommen.
Fehler:
Was mache ich falsch?
Vielleicht ein Problem mit den Zugriffsrechten. Probiere mal
chmod -R 777 /home/fimi/ampp
docker-compose up -d
Das hat leider keinen Erfolg gebracht.
Was zeigt
ls /home/fimi/ampp/docker/build/mysql
?
Dann stimmt der Pfad nicht. Bitte auch Gross-Kleinschreibung beachten.
Ist der build Ordner auf der gleichen Ebene wie der docker Ordner?
Ja. Ich hatte die “docker-compose.yml” erst im docker ordner, wie es oben im Bild zu sehen ist. Ein Verschieben in den ampp Ordner bringt aber den gleichen Fehler.
Das ist mein Verzeichniss-Baum:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAw4AAAP5CAIAAAAwt++7AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAFiUAABYlAUlSJPAAANMtSURBVHhe7P0xaBtZG7eNv8W/+IqveIq3eIqvCWyxhi0iS
Das Bild kam hier leider nicht an. Wenn LS schon einen Fehler bringt, stimmt der Pfad nicht:
ls: cannot access ‘/home/fimi/ampp/docker/build/mysql’: No such file or directory
Bitte den Pfad genau kontrollieren.
Ich überprüfe das nochmal genau.
Kann es sein, dass im Ordner “/ampp/build” noch weitere Ordner enthalten sind? Im Bild oben ist dieser nicht ausgeklappt und es scheint so als würde er leer sein.
Ich habe die Pfade nochmals gecheckt aber keinen Unterschieb feststellen können.
In deinem Bild ist zu sehen, dass im Ordner build noch 3 Objekte drin sind. Welche Objekte sind das? Im Bild oben aus dem Tutorial ist der Ordner build nicht aufgeklappt und er scheint leer zu sein.
Im Tutorial, bevor man die docker-compose.yml schreiben soll, steht das man
Den Ordner gibts es auch nicht in der Übersicht oben.
Ich habe ihn erstellt und die *.yml Datei darin erstellt. Zusätzliche habe ich
im Ordner Build 3 Unterordner: mysql, apache und phpmyadmin erstellt.
Der erste Fehler, das der Pfad nicht existieren soll kommt jetzt nicht mehr.
Dafür ein anderer:
Vielen Dank für die Hilfe.
Gruß Alexander
Hier eine bessere Übersicht der Ordnerstruktur (einige Unterordner werden nach erfolgreichem Start autom. anfgelegt):
Ich habe heute morgen das erste mal Docker gestartet und das Tutorial durchgearbeitet, alles völlig problemlos. Bin nun dieser Anleitung hier gefolgt (nichts geändert), erstmal auch alles gut: Alle Container laufen. Wenn ich aber http://127.0.0.1/info.php im chrome aufrufe kommt:
Die Website ist nicht erreichbar127.0.0.1 hat die Verbindung abgelehnt.Versuche Folgendes:
ERR_CONNECTION_REFUSED
Firewall ist es nicht, habe sie eben testweise komplett ausgeschaltet. Proxy nutze ich nicht. http://localhost:8080/ geht auch nicht. Firefox geht auch nicht. Auf den phpmyadmin-container kann ich beispielsweise normal zugreifen.
Mein System: WIndows 10 Professional / alle updates; Docker Desktop 4.14.0
Hat hier vielleicht jemand ne idee woran das liegen könnte?
Ciao, Jörg
Bitte mal http://127.0.0.1:8080/info.php testen. Wenn Du IPV6 aktiviert hast, könnte localhost auf die IPV6-Adresse aufgelöst werden.
http://127.0.0.1:8080/info.php geht leider auch nicht. IPV6 ist bei meinem Ethernet-Adapter nicht aktiv. im apache-container sieht das log so aus:
nur infos und warnings: sieht so aus, als ob das laufen würde.Kann man irgendwie checken, ob apache wirklich läuft? Oder würde Docker sich sonst beschweren?
Ciao, Jörg
Docker läuft, auch wenn Apache es nicht tut :-)
Das Log sieht aber OK aus.
Testen kannst Du z.B. mit
telnet 127.0.0.1 8080
Antwort sollte dann so aussehen:
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Auch die IPV4-Adresse deines PCs sollte funktionieren, z.B.
http://192.168.0.165:8080
Bitte mal noch ggf. Antivirensoftware abschalten, das diese sich oft in den Netzwerkverkehr einhängt und filtert …
Kann es sein, dass docker-compose.yml falsch ist? Du hast:
So funktioniert es:
Ciao, Jörg
Autsch – stimmt. Danke für den Hinweis :-)
Das läuft übrigends nicht auf Apple Silicon Geräten. Die docker images von apache und phpmyadmin sind noch nicht arm kompatibel
Stimmt – Apache und PHPMyAdmin schmieren leider ab. Ich schau mal nach einer Alternative …
Konnte das Apache- und PhpMyAdmin-Image entsprechend patchen. Siehe letzter Abschnitt “Docker: Bitnami Images auf Macs mit Apple Silicon lauffähig machen”. Vor Test bitte alte Container und Images löschen, damit sie komplett neu aufgebaut werden.
Vielen Dank für das sehr gute Tutorial. Soweit läuft die Installation. :-)
Leider kann ich aus meinem PHP-Script keine Verbindung zum MySQL-Server herstellen.
PHPmyAdmin läuft und ich sehe darin auch den User admin. Eine Datenbank(testdatenbank) habe ich angelegt und dem User admin die Rechte dazu vergeben. Doch die “normale” Anbindung in PHP funktioniert nicht:
Fehler bei der DB-Verbindung: Connection refused
Physisch läuft MySQL ja in einem getrennten Container. Ersetze daher localhost (127.0.0.1) durch den Containernamen:
Prima, läuft, danke für die schnelle Unterstützung.
Danke für Dein Feedback hier :-)
Habe den Beitrag gerade ergänzt. Falls noch mal jemand über das Problem stolpern sollte ….
In order to get PhpMyAdmin to work I had to change the config:
from
to
Thanks for the feedback!
Hallo, bin auch neu im Thema und hab langsam alles rekonstuiert. Danke für das Beispiel welches komplett zu meinem Thema passt :-) Natürlicherweise kahm ein Fehler:
yaml: line 56: did not find expected key
hab aber schon beim compose den fehler – zuerst line52 und jetzt immer 56….. hab alle kommentare gelesen und bei phpmyadmin
environment:
– DATABASE_HOST=mysql
schon getauscht. Leider verstehe ich die logic wohin das ref. nicht ganz !
Kann man wo mehr Log sehen – also wo er genau steckt ? Die built Ordnerstruktur habe Ich mir geschenkt da ja kein apple im spiel ist… – kann man somit das built: im compose File auch auskommentieren ? Version kann nicht schuld sein oder – hab mit 3.0 und 3.7 probiert, bei mir geht normal 3.7 aber ist doch abwärtskompatiebel.. DANKE
hab das yml so modifiziert das er es hochzieht. Nur apache streikt:
AH00526: Syntax error on line 18 of /opt/bitnami/apache/conf/bitnami/bitnami-ssl.conf:
SSLCertificateFile: file ‘/opt/bitnami/apache/conf/bitnami/certs/server.crt’ does not exist or is empty
Muss man das File in C:\docker\ampp\docker\apache\certs ablegen – oder generieren oder gehts auch OHNE ?
Anscheinend hat Bitnami inzwischen das Image geändert. Das hier sollte helfen:
https://www.sitepoint.com/community/t/how-to-fix-apache-bitnami-start-error/340910
Interessant ist auch, dass ich mich nicht über die externe IP auf PhpMyAdmin anmelden kann.
Folgende Fehler sage er mir:
Jetzt habe ich über das NavicatLite eine Verbindung erfolgreich hergestellt.
aber was habe ich vergessen das ich mich über PhpMyAdmin anmelden kann?
Siehe Beitrag:
Guten Tag, ich bin noch neu in der Docker Geschichte :-)
Ich werde es mal nach bauchen und sage schon mal vielen Dank für das howto.
Danke für den Dank :-)
Container dstack-mysql startet nicht mit :/bitnami/mysql/data
Fehlermeldung?
Hast Du diesen Ordner angelegt?
./docker/mysql/data
Versuch mal die Schreibrechte vom Mysql-ordner zu setzen, bei mir war dieser nach dem ersten Start schreibgeschützt, das hat das Problem bei mir gelöst