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:
Da später 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 |
--- # Docker Web Development Stack (dstack) 1.0.3 # # Runs Apache, MySQL, PHP, Redis and PhpMyAdmin # SSL is preconfigured. # Imagemagick and XDebug are activated. # # Run with # docker-compose up -d # # (C)2020 Harald Schneider # version: "3" services: # --- MySQL 5.7 # mysql: container_name: "dstack-mysql" image: bitnami/mysql:5.7 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 # --- PHP 7.4 # php: container_name: "dstack-php" image: bitnami/php-fpm:7.4 depends_on: - redis volumes: - ./docker/www:/app:delegated - ./docker/php/php.ini:/opt/bitnami/php/etc/conf.d/php.ini:ro # --- Apache 2.4 # apache: container_name: "dstack-apache" image: bitnami/apache:2.4 ports: - '80:8080' - '443:8443' depends_on: - php volumes: - ./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: "dstack-redis" image: bitnami/redis:6.0 environment: - REDIS_PASSWORD=YOUR_PASSWORD_HERE # --- PhpMyAdmin latest # Acccess via # http://127.0.0.1:81 or https://127.0.0.1:8143 # Login with user root and mysql-password. # phpmyadmin: container_name: "dstack-phpmyadmin" image: bitnami/phpmyadmin:latest depends_on: - mysql ports: - '81:8080' - '8143:8443' environment: - DATABASE_HOST=host.docker.internal volumes: dstack-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.
Viel Spaß beim dockern :-)