Moderne Webanwendungen bestehen selten aus einem einzigen Prozess. Typisch ist eine Kombination aus Applikationsserver, Datenbank und Cache – drei separate Container, die miteinander kommunizieren müssen. Mit einzelnen docker run-Befehlen wird das schnell unübersichtlich. Docker Compose löst dieses Problem: Eine einzige YAML-Datei beschreibt die gesamte Anwendungslandschaft, und mit einem Befehl wird alles gestartet.
Was ist Docker Compose?
Docker Compose ist ein Werkzeug zur Definition und Ausführung von Multi-Container-Docker-Anwendungen. Seit Docker Compose V2 ist es als Plugin direkt in die Docker CLI integriert: docker compose up (ohne Bindestrich) ist der moderne Befehl. Die Konfiguration erfolgt in einer compose.yaml- (empfohlen) oder docker-compose.yml-Datei.
Aufbau der docker-compose.yml
Eine Compose-Datei besteht aus drei Hauptabschnitten:
- services – die einzelnen Container mit Image, Ports, Umgebungsvariablen und Abhängigkeiten
- volumes – persistente Datenspeicher, die Container-Neustarts überdauern
- networks – virtuelle Netzwerke, über die Container miteinander kommunizieren
Häufige Muster: App + Datenbank + Cache
Das klassische Drei-Schichten-Muster sieht so aus: Eine Node.js- oder PHP-Applikation kommuniziert mit einer PostgreSQL- oder MySQL-Datenbank und nutzt Redis als Cache. In Compose wird das durch drei Service-Einträge abgebildet, die über ein gemeinsames Netzwerk miteinander verbunden sind. Der Applikationsserver kann die anderen Services direkt über ihren Service-Namen (db, cache) ansprechen – Docker Compose übernimmt die interne DNS-Auflösung.
Umgebungsvariablen
Sensible Konfiguration wie Datenbankpasswörter gehört nicht fest in die Compose-Datei. Stattdessen liest Compose automatisch eine .env-Datei im selben Verzeichnis aus. Variablen können dann als ${VARIABLE_NAME} referenziert werden. Die .env-Datei sollte niemals in ein Git-Repository eingecheckt werden.
Health Checks
Mit dem healthcheck-Schlüssel lässt sich definieren, wann ein Container als "healthy" gilt. Das ist besonders wichtig, wenn ein Service auf einen anderen warten muss – depends_on allein prüft nur, ob der Container gestartet ist, nicht ob der Dienst darin bereit ist:
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
docker compose watch (verfügbar ab Compose 2.22) werden Dateiänderungen im Projektverzeichnis automatisch in den laufenden Container synchronisiert – ideal für die Entwicklung, ohne den Container neu starten zu müssen.
Praxisbeispiel: WordPress + MySQL + phpMyAdmin
Das folgende Beispiel startet einen vollständigen WordPress-Stack mit Datenbankadministration über phpMyAdmin:
services:
db:
image: mysql:8.0
restart: always
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: wordpress
MYSQL_USER: wpuser
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- db_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
wordpress:
image: wordpress:latest
restart: always
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wpuser
WORDPRESS_DB_PASSWORD: ${MYSQL_PASSWORD}
WORDPRESS_DB_NAME: wordpress
depends_on:
db:
condition: service_healthy
phpmyadmin:
image: phpmyadmin:latest
restart: always
ports:
- "8081:80"
environment:
PMA_HOST: db
depends_on:
- db
volumes:
db_data:
Mit docker compose up -d startet der gesamte Stack im Hintergrund. WordPress ist danach unter http://localhost:8080, phpMyAdmin unter http://localhost:8081 erreichbar.
Vergleich: Docker Compose vs. Kubernetes vs. Podman Compose vs. Docker Swarm
| Kriterium | Docker Compose | Kubernetes | Podman Compose | Docker Swarm |
|---|---|---|---|---|
| Zielgruppe | Entwicklung & kleine Prod. | Großskaliger Prod.-Betrieb | Entwicklung (rootless) | Kleine Prod.-Cluster |
| Komplexität | Gering | Hoch | Gering | Mittel |
| Multi-Node | Nein | Ja | Nein | Ja |
| Auto-Scaling | Nein | Ja (HPA) | Nein | Manuell |
| Root-Daemon erforderlich | Ja (Docker) | Nein (kubelet) | Nein (rootless) | Ja (Docker) |
| Lernkurve | Sehr flach | Steil | Flach | Moderat |
Nützliche Compose-Befehle im Überblick
docker compose up -d– Stack im Hintergrund startendocker compose down -v– Stack stoppen und Volumes löschendocker compose logs -f– Logs aller Services live verfolgendocker compose ps– Status aller Services anzeigendocker compose exec app bash– Shell im App-Container öffnen
Weitere Beispiele und offizielle Compose-Spezifikation findet man in der Compose Specification.
Häufig gestellte Fragen
- Was ist der Unterschied zwischen compose.yaml und docker-compose.yml?
- Inhaltlich sind beide identisch.
compose.yamlist der von der Compose Specification empfohlene Dateiname. Docker Compose erkennt beide Varianten automatisch. - Kann ich Docker Compose in der Produktion einsetzen?
- Für einfache Szenarien auf einem einzelnen Server ist das durchaus üblich und praktikabel. Für Multi-Server-Setups mit hoher Verfügbarkeit sollte man auf Kubernetes oder Docker Swarm ausweichen.
- Wie aktualisiere ich ein einzelnes Service-Image ohne Downtime?
- Mit
docker compose pull <service>das neue Image herunterladen und danndocker compose up -d --no-deps <service>ausführen. Der betroffene Container wird dabei kurz neu gestartet. - Was ist Podman Compose und wann sollte ich es nutzen?
- Podman Compose ist eine Alternative zu Docker Compose, die mit Podman als rootloser Container-Runtime arbeitet. Es ist besonders auf Linux-Systemen interessant, wo kein Docker-Daemon laufen soll oder darf.