ADMIN

2021

07

2021-07-01T12:00:00

Container- und Applikationsmanagement

SCHWERPUNKT

087

Containermanagement

Docker

Container mit Docker-Compose anpassen

Hafenmeister

von Dr. Matthias Wübbeling

Veröffentlicht in Ausgabe 07/2021 - SCHWERPUNKT

Die Bereitstellung und der produktive Betrieb von Software in Containern hat sich in den letzten Jahren als sinnvoll und praktikabel erwiesen. Immer mehr Anbieter kommerzieller Software ermöglichen daher auch die Nutzung ihrer Anwendung in Docker-Containern. In diesem Artikel zeigen wir Ihnen, wie Sie mit Docker-Compose den Betrieb von Anwendungen an Ihre eigene Infrastruktur anpassen.

Ein Sprichwort aus der Schifffahrt sagt im übertragenen Sinne: Auf jedem Containerschiff, das dampft und segelt, ist einer, der die Dienste regelt. Eine Idee, die maßgeblicher Treiber für den Erfolg von Docker ist, sind sogenannte Microservices, die jeder einen eigenen Container als Laufzeitumgebung erhalten. Dienste also, die sich genau einer Aufgabe widmen und sich separat von anderen benötigten oder abhängigen Diensten installieren und verwalten lassen. Viele moderne Anwendungen sind eine Kombination unterschiedlicher voneinander abhängiger Komponenten, die sich im Grunde separat als einzelne Dienste betreiben lassen. Eine organisatorische Trennung erlaubt die Nutzung und Wartung einzelner Bestandteile, ohne direkt alle Teile der Anwendung zu beeinträchtigen.
Verwenden Sie sonst mehrere Anwendungen auf demselben Hostsystem, sind Probleme bei der Auflösung von Abhängigkeiten vorprogrammiert. Können Sie für jede Anwendung die Abhängigkeiten aber in einem Container bündeln, stellen Sie mit Docker auf demselben Host schnell mehrere Versionen von Systembibliotheken oder Datenbanken für unterschiedliche Anwendungen zur Verfügung. Dabei lassen sich alle Abhängigkeiten direkt in den einen Container der Anwendung integrieren.
Der Betrieb unterschiedlicher Dienste innerhalb eines Containers ist zwar am Ende auch zielführend, widerspricht aber der Grundidee der Isolation einzelner Dienste. Lassen sich die abhängigen Dienste über ein Netzwerk-Protokoll anbinden, erstellen Sie mit Docker eigene virtuelle Netzwerke und starten für jeden Dienst einen eigenen Container. Die notwendige Kommunikation zwischen den Komponenten findet dann über Containergrenzen hinweg statt.
Ein Sprichwort aus der Schifffahrt sagt im übertragenen Sinne: Auf jedem Containerschiff, das dampft und segelt, ist einer, der die Dienste regelt. Eine Idee, die maßgeblicher Treiber für den Erfolg von Docker ist, sind sogenannte Microservices, die jeder einen eigenen Container als Laufzeitumgebung erhalten. Dienste also, die sich genau einer Aufgabe widmen und sich separat von anderen benötigten oder abhängigen Diensten installieren und verwalten lassen. Viele moderne Anwendungen sind eine Kombination unterschiedlicher voneinander abhängiger Komponenten, die sich im Grunde separat als einzelne Dienste betreiben lassen. Eine organisatorische Trennung erlaubt die Nutzung und Wartung einzelner Bestandteile, ohne direkt alle Teile der Anwendung zu beeinträchtigen.
Verwenden Sie sonst mehrere Anwendungen auf demselben Hostsystem, sind Probleme bei der Auflösung von Abhängigkeiten vorprogrammiert. Können Sie für jede Anwendung die Abhängigkeiten aber in einem Container bündeln, stellen Sie mit Docker auf demselben Host schnell mehrere Versionen von Systembibliotheken oder Datenbanken für unterschiedliche Anwendungen zur Verfügung. Dabei lassen sich alle Abhängigkeiten direkt in den einen Container der Anwendung integrieren.
Der Betrieb unterschiedlicher Dienste innerhalb eines Containers ist zwar am Ende auch zielführend, widerspricht aber der Grundidee der Isolation einzelner Dienste. Lassen sich die abhängigen Dienste über ein Netzwerk-Protokoll anbinden, erstellen Sie mit Docker eigene virtuelle Netzwerke und starten für jeden Dienst einen eigenen Container. Die notwendige Kommunikation zwischen den Komponenten findet dann über Containergrenzen hinweg statt.
Um Ihnen die Verwaltung mehrerer Container, notwendiger Netzwerke und globaler Einstellungen von Anwendungen mit Docker zu erleichtern, gibt es Compose. Für den nun folgenden Teil gehen wir davon aus, dass Sie Docker bereits verwendet haben, dass Sie wissen, wie Sie mit Dockerfiles entsprechende Images erstellen beziehungsweise anpassen und dass Sie Erfahrung in der Benutzung von Docker-Registrierungen wie Docker Hub haben. Darüber hinaus müssen Sie docker-compose auf Ihrem System installiert haben. Mit Compose definieren Sie die Umgebung der installierten Anwendung innerhalb einer YAML-Datei und können so mit nur einem Kommando die Anwendung im Ganzen oder auch nur einzelne Dienste der Anwendung starten, stoppen oder aktualisieren.
Listing 1: Compose-Beispieldatei
version: '3' services:     web:         build: .         ports:            - "8080:80"            - "8443:443"         volumes: - ./:/usr/share/nginx/html
Compose-Dateiformat
YAML ist eine 2004 veröffentlichte Sprache zur vereinfachten Datenserialisierung und eine Obermenge der bekannteren Java-Script Object Notation (JSON). Insbesondere eignet es sich damit zum Austausch und Speichern komplexer Objekte in Form von assoziativen Listen, Arrays und Skalaren. Mit YAML erhalten die Dateien von Compose eine für Menschen einfach lesbare Struktur. So können Sie diese einfach verstehen, ändern oder erweitern.
Den Aufbau einer Compose-Datei – diese tragen meist den Default-Namen "docker-compose.yaml" – sehen Sie als Beispiel in Listing 1. Zur Erläuterung der Struktur wird hier zunächst nur ein einzelner Container ohne Abhängigkeiten definiert.
Geben Sie als ersten Eintrag die Version des Dateiformats an. Compose hat im Laufe der Zeit unterschiedliche, zum Teil inkompatible Dateiformate definiert, um die Möglichkeiten der Spezifikation an die Funktionalität von Docker anzupassen. Zum Zeitpunkt der Erstellung dieses Artikels ist Version 3.8 aktuell, die Docker ab Version 19.03 unterstützt [1]. Bei der Versionsangabe reicht es, die Major-Version anzugeben.
Jede Compose-Datei enthält die Definition von Diensten mit dem Schlüsselwort "services". Services beschreibt eine Map und die einzelnen Dienstedefinitionen sind über Namen referenziert. Um wie im Beispiel einen Webdienst zu erstellen, geben Sie dort den Namen "web" an und definieren anschließend für diesen Service mit dem Schlüsselwort "build", dass ein Dockerfile im Arbeitsverzeichnis für die Erstellung des Images genutzt werden soll.
Unter "ports" geben Sie ein Array von TCP- beziehungsweise UDP-Ports an, die der Container auf dem Hostsystem verwenden soll, und mit "volumes" definieren Sie Verzeichnisse im Dateisystem des Hosts, die in das Dateisystem des Containers eingebunden werden sollen. Docker bietet auch die Möglichkeit, anonyme oder referenzierbare Volumes (Named Volumes) einzubinden. Dafür erstellen Sie in der Compose-Datei mit dem Schlüsselwort "volumes" einen eigenen Bereich auf der obersten Ebene und referenzieren darin dann definierte Volumes mit ihrem Namen in den einzelnen Containern. Nach dem Doppelpunkt geben Sie den Pfad innerhalb des Containers mit an.
Wenn Sie zu Testzwecken spontan kein Dockerfile zum Bau eines Webdienstes zur Hand haben, erstellen Sie eine leere Datei mit dem Namen "Dockerfile" und fügen lediglich die folgende Zeile hinzu:
FROM nginx
Damit wird ein unverändertes nginx-Image aus der Docker-Hub-Registrierung für den Container verwendet. Anschließend starten Sie den Container mit
docker-compose up
Öffnen Sie nun den Browser und geben die URL "http://localhost/" ein, sollten Sie einen Zugriffsfehler (403) erhalten. Das liegt an fehlenden Rechten zur Anzeige des Verzeichnisinhalts. Legen Sie in Ihrem Arbeitsverzeichnis noch eine "index.html"-Datei mit beliebigem Inhalt an, bekommen Sie beim Neuladen der Seite diesen Inhalt angezeigt. Damit haben Sie den ersten Dienst mit Compose erstellt. Die Ausgabe des Serverlogs zeigt Compose standardmäßig auf der Konsole. Ihre HTTP-Anfragen sollten Sie dort also in den nginx-Logdaten nachvollziehen können. Mit "Ctrl + c" beenden Sie den Container wieder.
Abhängigkeiten berücksichtigen
Am Beispiel der Projektmanagement-Anwendung Jira des britischen Anwendungsentwicklers Atlassian lässt sich die Erstellung einer Compose-Datei mit einfachen Abhängigkeiten demonstrieren. Atlassian bietet für einige seiner Produkte fertige Docker-Container an [2]. Die Dokumentation zu diesen Containern umfasst dabei lediglich die Konfiguration und den Start mit der Docker-CLI. Eine Compose-Datei stellt Atlassian nicht zur Verfügung. Die Auswahl des Datenbankservers wird über Umgebungsvariablen des Containers gesteuert. Für unseren Anwendungsfall verwenden wir Compose und wählen PostgreSQL als Datenbankserver. Diesen betreiben Sie ebenfalls in einem Container und verwalten ihn gemeinsam mit Jira. Listing 2 zeigt die entsprechende Compose-Datei.
Listing 2: Compose und Jira nutzen
version: '3' services:       jira:            image: atlassian/jira-software:latest            restart: always            ports:            - 8080:8080           volumes:            - /opt/jira/appdata:/var/atlassian/application-data/jira            depends_on:            - database            links:            - database:database            environment:            - ATL_DB_DRIVER=org.postgresql.Driver            - ATL_DB_TYPE=postgres72            - ATL_JDBC_URL=jdbc:postgresql://database:5432/jira            - ATL_JDBC_USER=jira            - ATL_JDBC_PASSWORD=it-administrator       database:            image: postgres:12            restart: always            ports:            - 5432:5432            volumes:            - /opt/jira/database:/var/lib/postgresql/data            environment:                POSTGRES_PASSWORD: it-administrator                 POSTGRES_USER: jira                 POSTGRES_DB: jira
Zusätzlich zum Jira-Container wird in der Compose-Datei also der Postgres-Container konfiguriert. Statt wie im ersten Beispiel mit "build" einen neuen Container aus einem vorliegenden Dockerfile zu erstellen, lässt sich mit "image" jeweils direkt ein Image aus der Docker-Hub-Registrierung laden. Das spart Zeit, denn die Images dort wurden bereits von ihren Entwicklern aus einem Dockerfile erstellt und anschließend der Öffentlichkeit zur Verfügung gestellt.
Das Schlüsselwort "restart" ist äquivalent zu der von Docker bekannten Option und reicht die Einstellungen zum Neustart eines Containers, etwa mit "on-failure" im Fehlerfall, an Docker weiter. Die Abhängigkeiten eines Containers definieren Sie mit "depends_on". Dabei handelt es sich um ein Array, ein Container kann also von mehreren anderen Containern abhängig sein. Die Reihenfolge ist dabei unwichtig. Als Werte geben Sie die Dienstnamen innerhalb der Compose-Datei an, in diesem Fall also "database" für die Abhängigkeit zu Postgres. Durch mehrere Abhängigkeiten der Container untereinander entsteht eine Hierarchie. Diese bestimmt etwa die Startreihenfolge der Container. In diesem Fall startet also zuerst Postgres und anschließend Jira.
Die Angaben unter dem Schlüsselwort links abstrahieren den Zugriff auf andere Container über ein Netzwerk. Diese Funktion ist in Docker als veraltet gekennzeichnet und wird in einer zukünftigen Version entfernt. Die Empfehlung ist daher, in Compose-Dateien das Netzwerk explizit zu konfigurieren – wie Sie das umsetzen, sehen Sie in unserem Beispiel in Listing 3.
Listing 3: Netzwerkkonfiguration
jira:     […]     environment:     […]     - ATL_JDBC_URL=jdbc:postgresql://172.19.199.3:5432/jira     […]     networks:         jiranet:            ipv4_address: 172.19.199.2 database:     […]     networks:         jiranet:            ipv4_address: 172.19.199.3 nginx:     image: nginx     ports:         - 80:80     depends_on:       - jira     volumes:         - /opt/jira/nginx/nginx.conf:/etc/nginx/nginx.conf     networks:         jiranet:            ipv4_address: 172.19.199.4 networks:     jiranet:         driver: bridge         ipam:            driver: default            config:            - subnet: 172.19.199.0/24
Abschließend übergeben Sie mit dem Schlüsselwort "environment" notwendige Umgebungsvariablen zur Konfiguration der Container. Für Jira konfigurieren Sie so den Datenbanktreiber und den Typ der Datenbank sowie die Verbindungsparameter zu der Postgres-Instanz im Container "database". Die Umgebungsvariablen von Postgres definieren entsprechend den Namen der Datenbank und den zugehörigen Benutzer mit Passwort, der diese Datenbank verwenden darf. Für den Einsatz in einer Produktivumgebung stellt Jira weitere Umgebungsvariablen zur Konfiguration bereit. Damit können Sie etwa den Namen und die URL der Instanz oder eines Proxyservers konfigurieren, die Anzahl der Threads von der Tomcat-Instanz einstellen oder Laufzeitparameter für die Java-VM festlegen, etwa die reservierte oder maximale Heap-Größe. Starten Sie nun die gesamte Anwendung mit dem Kommando
docker-compose up
und beobachten Sie die Ergebnisse des Tomcat-Servers auf der Standardausgabe. Wenn Sie nach der Startsequenz in Ihrem Browser die URL "http://localhost:8080/" aufrufen, erhalten Sie den Konfigurationsdialog von Jira und können mit der Einrichtung und Anpassung Ihrer Jira-Instanz beginnen.
Netzwerke konfigurieren
Die Kommunikation über Netzwerkprotokolle hat sich seit langem für das Zusammenspiel unterschiedlicher Dienste etabliert. Daher ist die Konfiguration eines Netzwerks in Compose eine notwendige Aufgabe, wenn die entsprechende Anwendung noch andere Dienste verwendet, etwa einen Datenbankserver, einen Proxy-server oder einen Logdatenserver.
Zur Auslieferung von Jira soll in diesem Beispiel mit Nginx ein Proxy vorgeschaltet werden. Zusätzlich soll zur Erhöhung der Sicherheit auch der direkte Zugriff auf Port 8080 des Jira-Containers und auf Port 5432 des Postgres-Servers von außen nicht mehr möglich sein. Das lässt sich einfach durch ein eigenes Docker-Netzwerk für die gesamte Anwendung umsetzen. Dieses können Sie direkt in der Compose-Datei definieren. Es wird dann beim Deployment angelegt und beim Löschen zuverlässig wieder entfernt. Löschen Sie in der Datei aus Listing 2 die Angaben der "ports" und ergänzen Sie das Listing entsprechend um die Netzwerkkonfigurationen für die einzelnen Servicebeschreibungen und die neu hinzugekommene Konfiguration des Nginx-Containers.
Unter "networks " definieren Sie nun das mit jiranet benannte Netzwerk als Bridge und vergeben im IP-Addressmanagement-Bereich (ipam) ein Subnetz mit privaten IP-Adressen. Zusätzlich fügen Sie jedem Container einen Bereich "networks" hinzu, sofern Sie für das jiranet eine feste IP-Adresse zuweisen. So können die Dienste innerhalb der Container über die fest vergebenen IPs miteinander kommunizieren. Da Sie in diesem Fall keine Links mehr verwenden, müssen Sie auch die Verbindungsoption zur Datenbank in der Umgebungsvariable des Jira-Containers an die IP-Adressen anpassen. Die Konfigurationsdatei von Nginx unter "/opt/jira/nginx/nginx.conf" können Sie nach Ihren Wünschen anpassen. Eine minimalistische lauffähige Beispiel-Konfiguration finden Sie in Listing 4.
Listing 4: Minimalkonfiguration
events { } http {     server {         include /etc/nginx/mime.types;         server_name localhost;         location / {             proxy_pass http://172.19.199.2:8080;         }     } }
Wenn die Container aus dem vorigen Beispiel noch in Ihrem Terminal laufen, beenden Sie diese zunächst mit "Ctrl + c". Damit stoppen Sie die mit Compose verwalteten Container. Zum Entfernen der Container führen Sie dann noch das Kommando
docker-compose down
aus – wir sollen ja mit den angepassten Konfigurationen neue Container erstellen. Die Konfigurationen aus der Compose-Datei werden beim ersten Start des Containers in den Jira-Konfigurationen festgeschrieben, die unter "/opt/jira/" liegen. Wenn Sie also bereits das vorherige Beispiel ausprobiert haben, können Sie entweder den Ordner löschen oder, etwa weil Sie bereits eine Lizenz erzeugt und aktiviert haben, per Hand die Einstellungen in der Jira-Konfiguration ändern.
Dazu passen Sie in "/opt/jira/appdata" die Datei "dbconfig.xml" an, indem Sie die Zeile mit den "<url>"-Einstellungen entsprechend ändern. Bei einem erneuten Aufruf von docker-compose up wird nun zusätzlich Nginx als Proxy ausgeführt. Mit dem Argument "-d" schicken Sie Compose in den Daemon-Modus. Nach dem Start kehrt das Programm wieder zurück und Sie können in Ihrer Konsole weiterarbeiten. Sobald Jira gestartet ist, können Sie es unter der Adresse "http://localhost/" erreichen.
TLS aktivieren
Natürlich möchten Sie Nginx nicht bloß als HTTP-Proxy verwenden, sondern mit Zertifikaten etwa von Let's Encrypt auch TLS zur Verschlüsselung der Kommunikation einsetzen. Getreu dem Motto, dass jeder Dienst einen eigenen Container erhält, nutzen wir für die Erstellung der Schlüssel und Zertifikate einen eigenen Container. Hier bietet sich natürlich der offizielle Certbot-Container an. Da wir an den bestehenden Containern nichts mehr ändern möchten, nutzen wir für die Integration von Certbot die Möglichkeit der Override-Konfiguration von Compose. Dafür legen Sie die Datei "docker-compose.override.yaml" an und notieren dort alle Abweichungen an der zuvor in "docker-compose.yaml" gemachten Konfiguration. Als Vorlage verwenden Sie die Konfiguration aus Listing 5.
Listing 5: Certbot integrieren
version: '3' services:        nginx:           ports:              - 80:80             - 443:443           volumes:              - /opt/jira/nginx/nginx.conf:/etc/nginx/nginx.conf              - /opt/jira/nginx/webroot:/var/www/html              - /opt/jira/letsencrypt:/etc/letsencrypt        certbot:           image: certbot/certbot           container_name: certbot           volumes:              - /opt/jira/letsencrypt:/etc/letsencrypt              - /opt/jira/nginx_webroot:/var/www/html           depends_on: - nginx           command: certonly --webroot --webroot-path=/var/www/html --email it-administrator@example.com --agree-tos --no-eff-email -d it-administrator.de -d www.it-administrator.de           networks:                 jiranet:                    ipv4_address: 172.19.199.5
Passen Sie Ihre E-Mail-Adresse und die Domain in der unter "command" angegebenen Zeichenkette des Certbot-Containers an. Wenn Jira aus den vorigen Beispielen noch immer im Hintergrund läuft, können Sie nun einfach
docker-compose up -d
ausführen. So werden nur die laufenden Container, deren Konfiguration sich geändert hat, aktualisiert und anschließend Certbot einmalig ausgeführt. Wenn Sie diese Konfiguration das erste Mal starten, erstellt Certbot neue Zertifikate und hinterlegt diese in "/opt/jira/letsencrypt". Erst anschließend können Sie die Konfiguration von Nginx wie in Listing 6 erweitern, sodass auch verschlüsselte Verbindungen möglich sind.
Listing 6: Zertifikate einrichten
events { } http {     server {              include /etc/nginx/mime.types;              listen 80;              server_name it-administrator.de;              location / {                          return 301 https://$host$ request_uri;              }    }     server {              listen 443 ssl;              server_name it-administrator.de;              ssl_certificate/etc/letsencrypt/live it-administrator/fullchain.pem;              ssl_certificate_key/etc/letsencrypt/live/it-administrator/privkey.pem;              location / {                          proxy_pass http://172.19.199.2:8080;              }     } }
Damit die neue Konfiguration übernommen wird, müssen Sie nun Nginx noch einmal separat neu starten. Die anderen Container brauchen Sie dabei nicht mehr verändern. Der Neustart gelingt Ihnen mit dem Kommando
docker-compose restart nginx
Jetzt können Sie mit dem Browser die korrekte Funktion und den verschlüsselten Verbindungsaufbau überprüfen.
Die Nutzung von Let's Encrypt als Zertifizierungsstelle bringt die Notwendigkeit zur regelmäßigen Erneuerung der Zertifikate mit sich. Damit das automatisch etwa alle zwei Monate passiert, erstellen Sie einen Cronjob, der ebenfalls das Docker-Image von Certbot verwendet. Dafür benötigen Sie kein Compose, sondern Sie können für den Cronjob direkt das folgende Kommando verwenden
docker run --rm -v /opt/jira/letsencrypt:/etc/letsencrypt certbot renew -q
Im Erfolgsfall müssen Sie noch sicherstellen, dass Nginx die neuen Zertifikate rechtzeitig berücksichtigt. Das erreichen Sie durch einen regelmäßigen Neustart des Nginx-Containers mit Compose, wie oben gezeigt.
Updates und Backups
Das Update von Containern gestaltet sich mit Compose ebenfalls sehr einfach. Sie können im laufenden Betrieb mit dem Kommando
docker-compose pull
aktualisierte Container-Images aus der Registrierung laden. Wenn diese auf Ihrem System vorliegen, können Sie mit
docker-compose up -d
alle Container neu erstellen, die ein Update benötigen. Das lässt sich natürlich auch über Cronjobs in regelmäßigen Abständen durchführen. Allerdings sollten Sie dann die Tags der verwendeten Images berücksichtigen. Die grundsätzliche Verwendung von "latest" sollten Sie vermeiden, um Inkompatibilitäten mit neueren Versionen anderer Container auszuschließen. Nutzen Sie stattdessen die Tags der Major-Versionen, sind Sie in den meisten Fällen auf der sicheren Seite.
Zur Sicherung Ihrer Anwendungsdaten haben Sie unterschiedliche Optionen, je nachdem, was sich besser in Ihre bestehende Backupstrategie einbinden lässt. Wenn Sie Ihre Sicherungen direkt auf einen externen Backupspeicher schieben, dann können Sie hierfür natürlich wieder einen Docker-Container mit Ihrer bevorzugten Backupanwendung erstellen und über Cronjobs regelmäßig anstoßen. Wenn Sie die relevanten Verzeichnisse der anderen Container als Volumes in diesen Container einbinden, haben Sie anschließend ein umfassendes Backup.
Noch einmal sicherer ist es natürlich, wenn das Backupsystem die Sicherungen eigenständig vom Server herunterlädt und dieser von sich aus keinen Zugriff auf das Backupsystem hat. Für die Jira-Installation aus diesem Artikel genügt es, wenn Sie den Ordner "/opt/jira" in die Datensicherung einbinden. Dort liegen die Anwendungsdaten, die Datenbank sowie die Nginx-Konfiguration und die Let's Encrypt Schlüssel und Zertifikate. Bei komplexeren Szenarien müssen Sie zunächst vor dem Backup alle relevanten Daten zusammenstellen und gegebenenfalls mit einem weiteren Docker-Container die notwendigen Dateien aus Named Volumes Ihrer Container in Verzeichnisse des Hostsystems sichern.
Laufende Anwendungen überprüfen
Die wichtigsten Compose Befehle zum Aufsetzen einer Anwendungsumgebung haben Sie nun kennengelernt. Wenn Sie die Vorgänge in einer laufenden Anwendung überprüfen möchten, können Sie mit
docker-compose logs
die Ausgabe der Logdaten für alle Container bewirken. Um fortlaufend auch zukünftige Logs anzuzeigen, verwenden Sie "-f" als Argument. Sind Sie nur an einem Container interessiert, etwa dem von nginx, übergeben Sie dessen Namen einfach als weiteres Argument. Um also fortlaufend alle Nginx-Logeinträge zu beo-bachten, verwenden Sie etwa
docker-compose logs -f nginx
und beenden die Ausgabe bei Bedarf wieder mit "Ctrl + c". Die Anwendung läuft auch dann noch weiter im Hintergrund. Zum Beenden einer im Hintergrund laufenden Anwendung verwenden Sie einfach
docker-compose stop
und starten entsprechend mit "start" als Argument wieder. Benötigen Sie die erstellten Container, Netzwerke und Named Volumes nicht mehr, entfernen Sie die gesamte Umgebung mit
docker-compose down -v
Um Named Volumes über die Lebensdauer der Container-Umgebung zu erhalten, entfernen Sie die Option "-v" oder markieren Sie einzelne Named Volumes in der Compose-Datei mit der Option "external: true".
Fazit
In diesem Workshop haben Sie einen ersten Einblick in den Betrieb komplexer Anwendungen in Docker-Containern mit Compose erhalten. Ausgehend von den verfügbaren Containern der kommerziellen Projektmanagement-Anwendung Jira wurden die Komponenten als Microservices aufgesetzt und dann gemeinsam in Betrieb genommen. Abschließend haben Sie eine laufende Anwendung mit Postgres als Datenbank, einem mit Let's-Encrypt-Zertifikaten abgesicherten Nginx als Proxy, automatischen Updates und ein an Ihre Gegebenheiten angepasstes Backup. So können Sie zukünftig mit Hilfe von Docker-Compose noch weitere Anwendungen in Container auslagern und diese einfach verwalten.
(dr)
Link-Codes