Docker Logo
Docker Inc.
Donnerstag, den 11. Juni 2020 um 23:53 Uhr

Docker: Einrichtung einer neuen Entwicklungsumgebung mit nginx- & Apache-Servern

Docker bzw. Docker Desktop wird die neue Entwicklungs- und Testumgebung bereitstellen. Von dieser Container-Technologie verspreche ich mir auch langfristig viele Vorteile. Zu Beginn soll sie jedoch nur ein paar Multicontainer-Instanzen bereitstellen, die mit unterschiedlichen Setups aufwarten.

Docker ist ein Container-Dienst und soll zukünftig die Entwickungs- und Testumgebung stellen. Docker Desktop soll die Administration vereinfachen – besonders das Starten und Stoppen der Multi-Container, die via Docker Compose konfiguriert werden.

Docker: Anforderungen an die Entwicklungsumgebung

Anforderungen

  • Multi-Container mit Nginx, MariaDB, PHP
  • Multi-Container mit Apache, MariaDB, PHP
  • ein Code-Verzeichnis auf dem Hostsystem
  • ein MariaDB-Datenverzeichnis auf dem Hostsystem

Offene Punkte

  • Konfigurationsdateien besonders die HOSTS-Konfigurationen in den Servern müssen doppelt gepflegt werden

Vorteile

  • Schnelles Umschalten zwischen diversen Konfigurationen
  • Backup und Recovery der Environments via GIT

Langfristige Ziele

  • Deployment
  • Git/Gitlab
  • Atlassian-Tools
  • diverse IIS-Container für ASP.NET mit C#-Basis Entwicklungsprojekte

Docker: Ordnerstruktur der Entwicklungsumgebung

Wenn man sich die nötigen Ordner für die Apache- und Nginx-Environments anschaut, dann stellt man schnell fest, dass sie relativ identisch sind. Lediglich die Konfigurationsdateien für Apache und Nginx unterscheiden sich und natürlich die docker-compose.yml

Ordner für den Apache-Server

  • conf – für die Konfig-Files
  • mysql – Datenbank-Files
  • php – Konfig-Files
  • sites – htdocs-Verzeichnis

Ordner für den Nginx-Server

  • conf – für die Konfig-Files – JSON
  • mysql – Datenbank-Files
  • php – Konfig-Files
  • sites – htdocs-Verzeichnis

Ordner für den Nginx- & Apache-Server

Im Grunde werden für dieses Szenario nur unterschiedliche Server- & Docker-Konfigurationen benötigt. Deshalb könnte man die Ordner für beide Docker-Multi-Container auf die folgende Ordnerstruktur reduzieren.

  • apache – für docker-compose.yml
    • conf – für die Konfig-Files
  • nginx – für docker-compose.yml
    • conf – für die Konfig-Files – JSON
  • mysql – Datenbank-Files
  • php – Konfig-Files
  • sites – htdocs-Verzeichnis

Docker: Management-Tool-Installation

Nach dem Erstellen der Ordner installiere ich die von mir gewählten Tools für die Container-Verwaltung: Kitematic und Portainer.

Kitematic

Download Kitematic von GitHub. Entpacken von Kitematic in ein Verzeichnis und starten von Kitematic.

Portainer.io

Portainer kann nach der Installation von Docker Desktop einfach in der Konsole installiert werden. Beim Mounten des Volumes ist zu beachten, dass das Verzeichnis auf dem Host vorne steht.

$ docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v D:/Docker/portainer:/data portainer/portainer

Installation der Nginx- und Apache-Server

Für die Webserver in den Multi-Containern wird je eine docker-compose.yml benötigt. Compose ist ein Tool zum Definieren und Ausführen von Docker-Anwendungen für mehrere Container. In jedem dieser Container läuft ein Dienst. Für einen Apache mit PHP und MariaDB werden also drei Container benötigt. Diese werden in der Datei „docker-compose.yml“ definiert. Ebenso verhält es sich für den Nginx-Server.

Docker Compose: Aufbau der YAML-Datei

In der YAML-Datei wird dies zuerst angegeben. YAML ist eine vereinfachte Auszeichnungssprache zur Datenserialisierung. Das bedeutet, dass die Docker-Compose.yml der Syntax von YAML folgen muss, damit Docker Compose diese Definitionsdatei richtig lesen kann. Mit dieser Auszeichnungssprache können assoziative Listen (Arrays), Arrays und Einzelwerte (Skalare) abgebildet werden. Für Docker Compose Files werden dafür assoziative Arrays und Listen benötigt.

Es wurde Docker Version 19.0.3 installiert. Mit dieser Version ist die Docker Compose File Version auf Version 3.8 gestiegen. Diese Version muss zum Beginn jeder Datei angegeben werden.

version: '3.7'

Services kombinieren einzelne Container zu einem Multi-Container. Das bedeutet, dass wir ein assoziative Array namens Service benötigen und drei weitere eine Ebene darunter für die einzelnen Container. Um eine tiefere Ebene zu erzeugen benötigt man einfach zwei Leerzeichen. Das sieht dann so aus:

services:
  web:
  php:
  mysql:

In der jeweils nächsten Ebene können jetzt wiederum assoziative Arrays entstehen, die die einzelnen Services definieren. Der Service „web“ ist abhängig von den beiden anderen Services.

services:
  web:
    depends_on:
      - php
      - mysql
  php:
  mysql:

Beginnen wir bei der Einrichtung mit dem MariaDB-Server. Als Image für den Container wird das mariadb-Image verwendet. Der Server läuft in jedem Multi-Container auf Port 3306. Der  Daten-Ordner wurde bereits angelegt. In die beiden WebServer-Ordnern kommt jetzt eine neue Datei. „.env“ heißt die Environment-File. In dieser werden Variablen definiert. Diese können dann in der Docker Compose eingesetzt werden.

Inhalt der „.env“ – Environment-File

#!/usr/bin/env bash
# See https://docs.docker.com/compose/environment-variables/#the-env-file

# Nginx bzw. Apache
NGINX_HOST=localhost
APACHE_HOST=localhost

# PHP
# See https://hub.docker.com/r/nanoninja/php-fpm/tags/
PHP_VERSION=latest

# MySQL
MYSQL_HOST=mysql
MYSQL_DATABASE=test
MYSQL_ROOT_USER=****
MYSQL_ROOT_PASSWORD=****
MYSQL_USER=****
MYSQL_PASSWORD=****

Inhalt des mysql-Service

version: '3.7'
services:
  web:
    depends_on:
      - php
      - mysql
  php:
  mysql:
    image: mariadb:latest
    ports:
      - "3306:3306"
    volumes:
      - "./../mysql:/var/lib/mysql"
    env_file:
      - ".env"
    environment:
      - MYSQL_DATABASE=${MYSQL_DATABASE}
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - MYSQL_USER=${MYSQL_USER}
      - MYSQL_PASSWORD=${MYSQL_PASSWORD}

Für den PHP-Service wird eine DockerFile im PHP-Verzeichnis verwendet. Deshalb wird statt des Images ein Build verwendet.

Inhalt der „Dockerfile“

FROM php:fpm

RUN docker-php-ext-install mysqli pdo pdo_mysql
RUN docker-php-ext-enable mysqli pdo pdo_mysql

Inhalt des php-Service

version: '3.7'
services:
  web:
    depends_on:
      - php
      - mysql
  php:
    build: ./../php
    volumes:
      - ./../sites:/var/www/html
  mysql:
    image: mariadb:latest
    ports:
      - "3306:3306"
    volumes:
      - "./../mysql:/var/lib/mysql"
    env_file:
      - ".env"
    environment:
      - MYSQL_DATABASE=${MYSQL_DATABASE}
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - MYSQL_USER=${MYSQL_USER}
      - MYSQL_PASSWORD=${MYSQL_PASSWORD}

Als letztes definieren wir die beiden Server. Apache und Nginx unterscheiden sich eigentlich nur in Image und Volumes.

Inhalt des Apache-Service

web:
    image: httpd:latest
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./../sites:/var/www/html/
      - ./conf:/usr/local/apache2/conf/
      - ./logs:/usr/local/apache2/logs/
    links:
      - mysql
    environment:
      - MYSQL_HOST=mysql
    depends_on:
      - php
      - mysql

Inhalt des Nginx-Service

web:
    image: nginx:latest
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./../sites:/var/www/html
      - ./../sites:/usr/share/nginx/html
      - ./conf/site.conf:/etc/nginx/conf.d/site.conf
    links:
      - mysql
    environment:
      - MYSQL_HOST=mysql
    depends_on:
      - php
      - mysql

In der Hosts-Datei von Windows werden zwei Einträge ergänzt um die Server testen zu können.

127.0.0.1 localhost
127.0.0.1 nginx.local
127.0.0.1 apache.local

Fehlt im nginx-Verzeichnis noch die Datei site.conf. Wichtig ist hier der der Teil mit FastCGI, sonst werden die PHP-Files nicht interpretiert.

server {
    index index.php index.html;
    server_name localhost;
	root /var/www/html;
	
	location ~ .php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+.php)(/.+)$;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

Beim Apache sieht es ähnlich aus. Auch hier brauchen wir die Conf-Dateien. Hier ist es jedoch nicht ganz so einfach. Entweder man startet den Multi-Container beim ersten Mal ohne das  Volume „conf“. Startet dann die Konsole und kopiert das Verzeichnis in diesem Fall mit dem Befehl: docker cp --archive apache_web_1:./usr/local/apache2/conf/ D:/Docker/apache/conf/. Oder man läd die den Apache auf der offiziellen Website herunter und erhält so die Conf-Dateien.

Jetzt können beide Container gestartet werden. Dazu wechselt man in der Konsole in zuerst in den Ordner „apache“. Mit „docker-compose up“ wird der Container initialisiert. Danach wechselt man auf der Konsole ins Verzeichis „nginx“ und führt ebenfalls „docker-compose up“ aus.

Beide Server sind via http://localhost erreichbar. Sie interpretieren PHP-Skripte und mit dem mySQL-Client erreicht man die Datenbank. Jetzt noch das SSL-Zertifikat nachrüsten und die fehlenden Server einrichten und die Entwicklung geht weiter.