Wer Anwendungen mit Docker betreibt, stößt früher oder später auf Dateien wie compose.yaml, Dockerfile und .env. Diese drei Dateien übernehmen unterschiedliche Aufgaben und bilden häufig die Grundlage für eine übersichtliche, reproduzierbare und wartbare Container-Umgebung.
Doch welche Datei ist wofür zuständig? Wie hängen die Konfigurationen zusammen? Und wie lassen sich beispielsweise Ports, Datenbankzugänge und andere Einstellungen verwalten, ohne ständig die Docker-Konfiguration verändern zu müssen?
In diesem Beitrag werden die wichtigsten Grundlagen Schritt für Schritt erklärt.
1. Was ist Docker Compose?
Docker Compose ist ein Werkzeug zur Verwaltung von Anwendungen, die aus einem oder mehreren Docker-Containern bestehen.
Eine typische Webanwendung besteht beispielsweise aus mehreren Komponenten:
- Webanwendung: Stellt die Benutzeroberfläche und die Anwendungslogik bereit.
- Datenbank: Speichert die benötigten Daten dauerhaft.
- Reverse Proxy (optional): Nimmt eingehende HTTP- und HTTPS-Anfragen entgegen und leitet sie an die entsprechenden Dienste weiter.
- Weitere Dienste (optional): Beispielsweise Redis als Cache oder ein Hintergrunddienst zur Verarbeitung von Aufgaben.
Ohne Docker Compose müssten diese Container einzeln gestartet und konfiguriert werden. Dabei wären unter anderem Netzwerke, Umgebungsvariablen, Portfreigaben und Datenspeicher manuell einzurichten.
Docker Compose vereinfacht diese Arbeit erheblich.
Die gesamte Anwendung wird in einer zentralen YAML-Datei beschrieben. Anschließend können alle zugehörigen Container gemeinsam gestartet, gestoppt und verwaltet werden.
Die Konfigurationsdatei heißt üblicherweise:
compose.yaml
Auch die ältere Bezeichnung docker-compose.yml wird weiterhin unterstützt.
2. Aufbau einer compose.yaml-Datei
Als Beispiel dient eine einfache Webanwendung, die zusammen mit einer PostgreSQL-Datenbank betrieben wird.
Die Konfiguration könnte folgendermaßen aussehen:
services:
webapp:
build: .
ports:
- "${APP_PORT:-8080}:8080"
environment:
ConnectionStrings__Default: "Host=db;Database=mischsoftware;Username=appuser;Password=${DB_PASSWORD}"
depends_on:
- db
restart: unless-stopped
db:
image: postgres:17
environment:
POSTGRES_DB: mischsoftware
POSTGRES_USER: appuser
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- db_data:/var/lib/postgresql/data
restart: unless-stopped
volumes:
db_data:
Diese Datei beschreibt zwei Dienste: eine Webanwendung und eine PostgreSQL-Datenbank.
Schauen wir uns die einzelnen Bestandteile genauer an.
services – Die Container einer Anwendung
services:
webapp:
db:
Unter services werden sämtliche Dienste definiert, die zur Anwendung gehören.
Im Beispiel sind dies:
webapp: Die eigentliche Webanwendung.db: Der PostgreSQL-Datenbankserver.
Docker Compose legt für die Dienste standardmäßig ein gemeinsames Netzwerk an.
Dadurch können sich die Container direkt über ihre Servicenamen erreichen.
Die Webanwendung kann den Datenbankserver beispielsweise über den Hostnamen db ansprechen. Eine separate IP-Adresse ist dafür nicht notwendig.
build – Ein Docker-Image erstellen
build: .
Mit build wird festgelegt, dass Docker Compose ein Image aus den vorhandenen Projektdateien erstellen soll.
Der Punkt (.) bezeichnet das aktuelle Verzeichnis als Build-Kontext.
Standardmäßig sucht Docker darin nach einer Datei namens Dockerfile.
Diese enthält die Anweisungen, mit denen das Docker-Image erstellt wird.
image – Ein vorhandenes Image verwenden
image: postgres:17
Anders als bei build wird hier ein bereits vorhandenes Docker-Image verwendet.
Das Beispiel verwendet PostgreSQL mit dem Versions-Tag 17.
Ist das Image lokal noch nicht vorhanden, kann Docker es aus einer entsprechenden Container-Registry herunterladen.
Hinweis: Ein Versions-Tag wie 17 bezeichnet nicht zwingend eine unveränderliche Image-Version. Für besonders reproduzierbare Bereitstellungen kann ein Image zusätzlich über seinen Digest festgelegt werden.
ports – Netzwerkports freigeben
ports:
- "8080:8080"
Die Portzuordnung besteht aus zwei Angaben:
HOST-PORT:CONTAINER-PORT
Die erste Zahl bezeichnet den Port auf dem Docker-Host. Die zweite Zahl bezeichnet den Port innerhalb des Containers.
Im Beispiel bedeutet dies:
- Port
8080auf dem Docker-Host wird freigegeben. - Eingehende Verbindungen werden an Port
8080des Containers weitergeleitet.
Läuft Docker beispielsweise auf einem Ubuntu-Server mit der IP-Adresse 192.168.1.100, wäre die Webanwendung grundsätzlich über folgende Adresse erreichbar:
http://192.168.1.100:8080
Voraussetzung ist, dass die Webanwendung innerhalb des Containers auf der richtigen Netzwerkschnittstelle und dem entsprechenden Port lauscht und keine Firewall- oder Netzwerkregel den Zugriff verhindert.
Die externe und interne Portnummer müssen nicht identisch sein.
Beispiel:
ports:
- "8090:8080"
Die Anwendung wäre dann über Port 8090 erreichbar, während der Webserver innerhalb des Containers weiterhin Port 8080 verwendet.
Sicherheitshinweis: Ohne Einschränkung der Host-IP kann Docker veröffentlichte Ports auf allen Host-Netzwerkschnittstellen bereitstellen. Soll ein Dienst nur lokal erreichbar sein, kann beispielsweise folgende Einstellung verwendet werden:
ports:
- "127.0.0.1:8080:8080"
Dadurch wird der Port nur an die Loopback-Adresse des Docker-Hosts gebunden.
environment – Umgebungsvariablen übergeben
environment:
POSTGRES_DB: mischsoftware
POSTGRES_USER: appuser
POSTGRES_PASSWORD: ${DB_PASSWORD}
Mit environment können Konfigurationswerte an den jeweiligen Container übergeben werden.
Im Beispiel erhält PostgreSQL drei Werte:
POSTGRES_DB: Name der anzulegenden Datenbank.POSTGRES_USER: Name des Datenbankbenutzers.POSTGRES_PASSWORD: Passwort des Datenbankbenutzers.
Das Passwort wird nicht direkt in die Compose-Datei geschrieben, sondern über die Variable ${DB_PASSWORD} eingesetzt.
Woher Docker Compose diesen Wert erhält, wird später bei der .env-Datei erklärt.
depends_on – Abhängigkeiten festlegen
depends_on:
- db
Die Anweisung depends_on legt fest, dass der Dienst webapp vom Dienst db abhängt.
Docker Compose startet dadurch zunächst die Datenbank und anschließend die Webanwendung.
Allerdings gibt es eine wichtige Einschränkung:
Die Startreihenfolge garantiert nicht, dass die Datenbank bereits vollständig betriebsbereit ist.
Eine Datenbank benötigt nach dem Containerstart möglicherweise einige Sekunden, bis sie Verbindungen akzeptiert.
Um auch die Betriebsbereitschaft zu berücksichtigen, können Healthchecks und erweiterte Abhängigkeitsbedingungen eingesetzt werden.
volumes – Daten dauerhaft speichern
volumes:
- db_data:/var/lib/postgresql/data
Docker-Container sind grundsätzlich austauschbar. Werden sie entfernt, gehen auch die Daten verloren, die ausschließlich im beschreibbaren Dateisystem des Containers gespeichert wurden.
Für Datenbanken wäre das problematisch.
Deshalb werden sogenannte Volumes verwendet.
Ein Volume stellt einen persistenten Speicherbereich zur Verfügung, der unabhängig vom Lebenszyklus einzelner Container existiert.
Im Beispiel wird das Volume db_data mit dem PostgreSQL-Datenverzeichnis verbunden.
Die Definition erfolgt zusätzlich am Ende der Compose-Datei:
volumes:
db_data:
Dadurch bleiben die Daten auch erhalten, wenn der Datenbankcontainer neu erstellt wird.
Wichtig: Ein Docker-Volume ersetzt kein regelmäßiges Datenbank-Backup.
restart – Automatischen Neustart konfigurieren
restart: unless-stopped
Diese Einstellung legt die Neustartrichtlinie des Containers fest.
unless-stopped bedeutet, dass Docker den Container bei Bedarf automatisch neu startet, solange er nicht ausdrücklich gestoppt wurde.
Das ist beispielsweise bei Serveranwendungen sinnvoll, die nach einem Neustart des Docker-Dienstes wieder verfügbar sein sollen.
3. Was ist eine .env-Datei?
Die .env-Datei dient dazu, Konfigurationswerte außerhalb der Docker-Compose-Datei zu verwalten.
Anstatt feste Werte direkt in die compose.yaml einzutragen, können diese in einer separaten Datei definiert werden.
Ein Beispiel:
# Konfiguration der Webanwendung
APP_PORT=8080
# Datenbankeinstellungen
DB_PASSWORD=MeinSicheresPasswort
# Anwendungsumgebung
ASPNETCORE_ENVIRONMENT=Production
Jede Einstellung besteht aus einem Namen und einem zugehörigen Wert.
Das Format lautet:
NAME=WERT
Kommentarzeilen beginnen mit einem #.
Der Vorteil liegt insbesondere darin, dass die eigentliche Docker-Konfiguration unverändert bleiben kann, während unterschiedliche Systeme jeweils eigene Einstellungen erhalten.
4. Wie verwendet Docker Compose die .env-Datei?
Docker Compose unterstützt die Ersetzung von Variablen innerhalb der YAML-Datei.
Beispielsweise:
ports:
- "${APP_PORT}:8080"
Steht in der .env-Datei:
APP_PORT=8080
wird daraus bei der Verarbeitung:
ports:
- "8080:8080"
Ein weiteres Beispiel ist das Datenbankpasswort:
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
Docker Compose ersetzt ${DB_PASSWORD} durch den entsprechenden Wert aus der Konfigurationsumgebung.
Dabei ist zu beachten, dass Werte nicht ausschließlich aus der .env-Datei stammen müssen. Auch Umgebungsvariablen der aufrufenden Shell können verwendet werden und haben bei der Variablenersetzung unter üblichen Bedingungen Vorrang.
Standardmäßig berücksichtigt Docker Compose eine passende .env-Datei. Über --env-file kann außerdem eine andere Datei angegeben werden.
5. Standardwerte für Variablen definieren
Nicht jede Einstellung muss zwingend in einer .env-Datei angegeben werden.
Docker Compose erlaubt auch Standardwerte.
Beispiel:
ports:
- "${APP_PORT:-8080}:8080"
Die Schreibweise ${APP_PORT:-8080} bedeutet:
- Wenn
APP_PORTgesetzt und nicht leer ist, wird der angegebene Wert verwendet. - Wenn die Variable nicht gesetzt oder leer ist, wird standardmäßig
8080verwendet.
Dadurch lassen sich sinnvolle Voreinstellungen direkt in der Compose-Datei hinterlegen.
Das erleichtert besonders die Einrichtung einer neuen Entwicklungsumgebung.
6. Unterschied zwischen .env, environment und env_file
Drei Begriffe, die leicht verwechselt werden können, sind .env, environment und env_file.
Obwohl sie ähnlich klingen, erfüllen sie unterschiedliche Aufgaben.
.env – Werte für Docker Compose
Die .env-Datei stellt Werte bereit, die Docker Compose beim Verarbeiten seiner Konfiguration verwenden kann.
Beispiel:
APP_PORT=8080
APP_MODE=Production
Wichtig: Nicht automatisch jede Variable aus dieser Datei wird an einen Container übergeben.
environment – Variablen gezielt an Container übergeben
services:
webapp:
environment:
ASPNETCORE_ENVIRONMENT: ${APP_MODE}
Hier wird der Wert von APP_MODE aus der Compose-Konfigurationsumgebung gelesen und dem Container als ASPNETCORE_ENVIRONMENT bereitgestellt.
Die Anwendung innerhalb des Containers kann diese Umgebungsvariable anschließend auslesen.
env_file – Eine Variablendatei an einen Container übergeben
Alternativ kann eine Umgebungsdatei direkt für einen Dienst angegeben werden:
services:
webapp:
env_file:
- ./webapp.env
Die Datei webapp.env könnte folgendermaßen aussehen:
ASPNETCORE_ENVIRONMENT=Production
LOG_LEVEL=Information
Die dort definierten Variablen werden dem Container als Umgebungsvariablen zur Verfügung gestellt.
Der entscheidende Unterschied:
Die standardmäßige .env unterstützt die Variablenersetzung durch Docker Compose. env_file definiert dagegen Umgebungsvariablen für einen bestimmten Container.
Beide Funktionen können kombiniert werden.
7. Warum sollten Konfigurationswerte ausgelagert werden?
Ein typisches Einsatzszenario ist die Entwicklung einer Anwendung auf einem lokalen Rechner und der spätere Betrieb auf einem Linux-Server.
Dabei unterscheiden sich möglicherweise bestimmte Einstellungen.
| Einstellung | Entwicklungsumgebung | Serverumgebung |
|---|---|---|
| Webserver-Port | 8080 | 8080 |
| ASP.NET Core Umgebung | Development | Production |
| Datenbankpasswort | Lokales Testpasswort | Separates Serverpasswort |
| Datenbank | Testdatenbank | Produktivdatenbank |
| Protokollierung | Debug | Information |
Die eigentliche compose.yaml kann in beiden Umgebungen identisch bleiben.
Lediglich die zugehörigen Konfigurationswerte unterscheiden sich.
Das hat mehrere Vorteile:
- Weniger Änderungen an der Compose-Datei.
- Geringeres Risiko versehentlicher Konfigurationsfehler.
- Einfachere Einrichtung neuer Systeme.
- Bessere Trennung zwischen Anwendung und Betriebsumgebung.
- Leichtere Verwaltung von Entwicklungs- und Produktionssystemen.
8. Sicherheit: Die .env-Datei und GitHub
Die .env-Datei kann sensible Informationen enthalten, beispielsweise Datenbankpasswörter, API-Schlüssel oder Zugangsdaten.
Daher sollten solche Dateien nicht ungeschützt in öffentlichen Git-Repositories abgelegt werden.
Eine übliche Lösung ist, die Datei über .gitignore auszuschließen.
Beispiel:
.env
.env.*
!.env.example
Dadurch ignoriert Git die lokale .env-Datei und weitere entsprechende Dateien. Die Vorlage .env.example wird dagegen nicht ausgeschlossen.
Eine .gitignore-Regel entfernt allerdings keine Dateien, die bereits von Git verfolgt werden. Entsprechende Dateien müssen gegebenenfalls separat aus der Versionsverwaltung entfernt werden.
Passwörter, die bereits veröffentlicht wurden, sollten als kompromittiert betrachtet und ausgetauscht werden.
Eine .env.example als Vorlage
Für ein gemeinsames Projekt empfiehlt sich eine Beispieldatei:
APP_PORT=8080
DB_PASSWORD=BITTE_EINTRAGEN
ASPNETCORE_ENVIRONMENT=Production
Diese Datei darf in das Repository aufgenommen werden, sofern sie keine echten Geheimnisse enthält.
Neue Entwickler oder Administratoren können sie kopieren und entsprechend anpassen.
Unter Ubuntu beispielsweise:
cp .env.example .env
Anschließend werden die benötigten Werte in der .env-Datei eingetragen.
Wichtig: Eine .env-Datei ist kein verschlüsselter Passwortspeicher. Umgebungsvariablen können unter anderem über bestimmte Docker-Verwaltungsbefehle sichtbar werden.
Für sicherheitssensible Produktionsumgebungen sollten geeignete Secret-Management-Lösungen geprüft werden.
9. Dockerfile, compose.yaml und .env – Wo liegt der Unterschied?
Diese drei Dateien erfüllen klar voneinander getrennte Aufgaben.
Dockerfile
Das Dockerfile beschreibt, wie das Docker-Image erstellt wird.
Ein vereinfachtes Beispiel für eine .NET-Anwendung:
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY ./publish .
EXPOSE 8080
ENTRYPOINT ["dotnet", "WebApp.dll"]
Dieses Beispiel setzt voraus, dass die Anwendung bereits in das Verzeichnis publish veröffentlicht wurde.
Das Dockerfile definiert unter anderem das Basis-Image, das Arbeitsverzeichnis und den Startbefehl.
Es beschreibt also den Aufbau des Images, nicht die vollständige Container-Infrastruktur.
compose.yaml
Die Compose-Datei beschreibt, wie ein oder mehrere Container ausgeführt werden.
Hier werden beispielsweise Ports, Netzwerke, Volumes, Umgebungsvariablen und Abhängigkeiten festgelegt.
.env
Die .env-Datei stellt konfigurierbare Werte bereit, die bei der Verarbeitung der Compose-Datei eingesetzt werden können.
Zusammengefasst:
| Datei | Aufgabe |
|---|---|
Dockerfile | Definiert, wie ein Docker-Image aufgebaut wird. |
compose.yaml | Definiert, wie Container betrieben werden und zusammenarbeiten. |
.env | Stellt variable Konfigurationswerte bereit. |
.gitignore | Legt fest, welche noch nicht verfolgten Dateien Git ignorieren soll. |
10. Eine sinnvolle Projektstruktur
Ein einfaches Projekt könnte folgendermaßen aufgebaut sein:
WebApp/
├── compose.yaml
├── Dockerfile
├── .env
├── .env.example
├── .gitignore
├── README.md
└── src/
└── ...
Die Dateien haben folgende Funktionen:
compose.yaml: Konfiguration der Container und ihrer Verbindungen.
Dockerfile: Beschreibung des Image-Builds.
.env: Lokale Konfigurationswerte, die nicht in Git gespeichert werden sollen.
.env.example: Vorlage für die benötigten Umgebungsvariablen.
.gitignore: Ausschluss bestimmter Dateien aus der Versionsverwaltung.
README.md: Dokumentation der Installation, Konfiguration und Nutzung.
src/: Quellcode der Anwendung.
Je nach Programmiersprache, Framework und Projektgröße kann die Struktur natürlich umfangreicher sein.
11. Die wichtigsten Docker-Compose-Befehle
Nachdem die Konfigurationsdateien erstellt wurden, kann die Anwendung über die Kommandozeile verwaltet werden.
Zunächst wechselt man in das Projektverzeichnis:
cd /pfad/zum/projekt
Container starten
docker compose up -d
Dieser Befehl erstellt und startet die benötigten Container.
Der Parameter -d steht für detached. Die Container werden im Hintergrund ausgeführt.
Images neu erstellen und Container starten
docker compose up -d --build
Dieser Befehl stößt den Build der entsprechend konfigurierten Images an und startet beziehungsweise aktualisiert die Container.
Das ist beispielsweise nach Änderungen am Dockerfile oder an der Anwendung sinnvoll.
Containerstatus anzeigen
docker compose ps
Zeigt die zur Compose-Anwendung gehörenden Container und deren aktuellen Status.
Containerprotokolle anzeigen
docker compose logs -f
Gibt die Protokolle der Container aus und verfolgt neue Einträge fortlaufend.
Das ist besonders bei der Fehlersuche hilfreich.
Container stoppen und entfernen
docker compose down
Dieser Befehl stoppt und entfernt die Container und die standardmäßig von Compose erstellten Netzwerke.
Benannte Volumes bleiben normalerweise erhalten.
Vorsicht ist beim zusätzlichen Parameter -v geboten:
docker compose down -v
Damit werden auch die durch Compose verwalteten Volumes entfernt. Bei einer Datenbank kann dies zum Verlust sämtlicher darin gespeicherter Daten führen.
Verarbeitete Konfiguration anzeigen
docker compose config
Mit diesem Befehl lässt sich überprüfen, welche Konfiguration Docker Compose aus den YAML-Dateien und den verfügbaren Variablen erzeugt.
Dies ist besonders praktisch, um Fehler bei der Variablenersetzung zu finden.
Verwendete Variablen anzeigen
docker compose config --environment
Dieser Befehl zeigt die für die Variablenersetzung verwendete Konfigurationsumgebung.
Achtung: Beide Konfigurationsbefehle können sensible Werte anzeigen. Ihre Ausgaben sollten deshalb nicht ungeprüft veröffentlicht werden.
12. Was passiert nach einer Änderung an der .env-Datei?
Eine häufige Frage ist, ob Docker nach einer Änderung der .env-Datei komplett neu gestartet werden muss.
In den meisten Fällen ist das nicht notwendig.
Wird beispielsweise ein Wert verändert, der über environment an einen Container übergeben wird, kann die Compose-Anwendung erneut angewendet werden:
docker compose up -d
Docker Compose erkennt relevante Änderungen an der Dienstkonfiguration und erstellt betroffene Container bei Bedarf neu.
Wichtig ist allerdings:
Eine Änderung der .env-Datei beeinflusst nur solche Einstellungen, die auch tatsächlich in der Compose-Konfiguration verwendet oder ausdrücklich an Container weitergegeben werden.
Wenn beispielsweise APP_PORT geändert wird, kann dies eine neue Portzuordnung zur Folge haben.
Bei einer Änderung des Datenbankpassworts gibt es eine zusätzliche Besonderheit: Viele Datenbank-Images verwenden ihre Initialisierungsvariablen nur bei der erstmaligen Einrichtung eines leeren Datenverzeichnisses.
Ein bestehendes PostgreSQL-Passwort wird deshalb nicht automatisch dadurch geändert, dass POSTGRES_PASSWORD in der .env angepasst wird. Das Datenbankpasswort muss gegebenenfalls innerhalb der Datenbank geändert werden.
13. Häufige Fehler und ihre Ursachen
Die Webanwendung ist nicht erreichbar
Mögliche Ursachen:
- Die Portzuordnung ist falsch.
- Die Anwendung lauscht innerhalb des Containers auf einem anderen Port.
- Der Webserver ist nur an
127.0.0.1innerhalb des Containers gebunden. - Eine Firewall blockiert die Verbindung.
- Der Container ist nicht gestartet oder wurde aufgrund eines Fehlers beendet.
- Die Netzwerkverbindung zwischen Client und Docker-Host funktioniert nicht.
Zur ersten Überprüfung eignen sich:
docker compose ps
docker compose logs
Eine Variable wird nicht übernommen
Möglicherweise wurde die Variable zwar in der .env-Datei definiert, aber nicht in der Compose-Datei verwendet oder an den entsprechenden Container weitergegeben.
Auch eine abweichende Schreibweise des Variablennamens oder eine andere aktive Konfigurationsquelle kann die Ursache sein.
Der Befehl
docker compose config
hilft bei der Überprüfung der endgültigen Compose-Konfiguration.
Die Datenbank verliert ihre Daten
Hier sollte kontrolliert werden, ob ein korrektes Volume eingerichtet ist.
Außerdem sollte geprüft werden, ob das Volume versehentlich entfernt wurde, beispielsweise durch docker compose down -v.
Die Webanwendung startet vor der Datenbank
Die einfache Angabe von depends_on garantiert noch nicht, dass der Datenbankdienst bereits Verbindungen akzeptiert.
Ein geeigneter Healthcheck in Kombination mit einer entsprechenden depends_on-Bedingung kann helfen, solche Startprobleme zu vermeiden. Zusätzlich sollte die Anwendung vorübergehende Verbindungsfehler sinnvoll behandeln können.
Fazit
Docker Compose bietet eine übersichtliche Möglichkeit, containerbasierte Anwendungen zu definieren und zu betreiben.
Die compose.yaml beschreibt die Dienste und ihre Zusammenarbeit. Das Dockerfile legt fest, wie eigene Docker-Images gebaut werden. Die .env-Datei ermöglicht es, variable Einstellungen aus der eigentlichen Compose-Konfiguration auszulagern.
Besonders bei Anwendungen, die sowohl lokal entwickelt als auch auf einem Server betrieben werden, bringt diese Trennung erhebliche Vorteile.
Die drei wichtigsten Grundregeln lauten:
- Dockerfile: Wie wird die Anwendung als Docker-Image bereitgestellt?
- Docker Compose: Wie werden die Container gestartet und miteinander verbunden?
- .env: Welche Einstellungen gelten für die jeweilige Umgebung?
Wer diese Unterschiede verstanden hat, besitzt bereits eine wichtige Grundlage für den strukturierten Einsatz von Docker in Entwicklungs- und Serverumgebungen.
Weiterführende Dokumentation:
- Docker Compose: https://docs.docker.com/compose/
- Compose-Dateireferenz: https://docs.docker.com/reference/compose-file/
- Variablen in Docker Compose: https://docs.docker.com/compose/how-tos/environment-variables/variable-interpolation/
- Docker-Volumes: https://docs.docker.com/engine/storage/volumes/
- Dockerfile-Referenz: https://docs.docker.com/reference/dockerfile/
