Docker Compose: Mehrere Container orchestrieren
Eine echte Anwendung besteht oft aus mehreren Containern. Mit Docker Compose beschreibst du Webserver, Datenbank und Co. in einer einzigen YAML-Datei und startest alles mit einem Befehl.
Echte Anwendungen bestehen selten aus nur einem Container. Meist brauchst du eine Web-App, eine Datenbank und vielleicht noch einen Cache. Alle einzeln mit langen docker run-Befehlen zu starten, ist mühsam und fehleranfällig. Docker Compose löst das: Du beschreibst alle Dienste in einer einzigen Datei und startest sie mit einem Befehl. In diesem Beitrag lernst du, wie das geht.
Was ist Docker Compose?
Docker Compose ist ein Werkzeug, mit dem du Multi-Container-Anwendungen deklarativ beschreibst. Statt jeden Container manuell zu starten, schreibst du eine Datei namens docker-compose.yml. Darin definierst du alle Dienste, Netzwerke und Volumes. Compose kümmert sich dann darum, alles in der richtigen Reihenfolge hochzufahren.
Aufbau einer compose-Datei
Die Datei ist im YAML-Format geschrieben. Einrückung ist hier entscheidend – nutze immer Leerzeichen, keine Tabs. Eine minimale Datei mit einem Webserver sieht so aus:
services:
web:
image: nginx:alpine
ports:
- "8080:80"Unter services listest du jeden Dienst. web ist hier ein frei gewählter Name. Mit image gibst du an, welches Image genutzt wird, und mit ports die Portweiterleitung.
Webserver und Datenbank kombinieren
Jetzt wird es spannend: Wir kombinieren eine eigene App mit einer PostgreSQL-Datenbank. Beachte, wie die App über depends_on an die Datenbank gekoppelt ist:
services:
app:
build: .
ports:
- "3000:3000"
environment:
DATABASE_URL: "postgres://user:geheim@db:5432/meinedb"
depends_on:
- db
db:
image: postgres:16
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: geheim
POSTGRES_DB: meinedb
volumes:
- db-data:/var/lib/postgresql/data
volumes:
db-data:Ein wichtiger Punkt: Innerhalb des Compose-Netzwerks erreichen sich die Dienste über ihren Namen. Deshalb steht in der DATABASE_URL einfach db als Hostname – nicht localhost.
Daten dauerhaft speichern mit Volumes
Container sind vergänglich: Löschst du sie, sind ihre Daten weg. Damit deine Datenbank nicht bei jedem Neustart leer ist, nutzt du ein Volume. Im Beispiel oben speichert db-data die Datenbankdateien dauerhaft auf dem Host. So bleiben deine Daten erhalten, auch wenn du den Container neu erstellst.
Die wichtigsten Compose-Befehle
Mit ein paar Befehlen steuerst du die gesamte Anwendung. Sie werden immer im Ordner mit der docker-compose.yml ausgeführt:
# Alle Dienste im Hintergrund starten
docker compose up -d
# Status aller Dienste anzeigen
docker compose ps
# Logs aller Dienste live verfolgen
docker compose logs -f
# Alles stoppen und Container entfernen
docker compose downMöchtest du auch die Volumes löschen (Achtung, Datenverlust!), hängst du -v an: docker compose down -v. Hast du dein App-Image geändert, baust du es mit docker compose up -d --build neu.
Umgebungsvariablen auslagern
Passwörter direkt in die YAML-Datei zu schreiben, ist keine gute Idee. Besser legst du eine .env-Datei an, die Compose automatisch einliest:
# .env
POSTGRES_PASSWORD=einsicheres_passwort
POSTGRES_USER=user
POSTGRES_DB=meinedbIn der compose-Datei greifst du dann mit der Syntax ${VARIABLE} darauf zu:
services:
db:
image: postgres:16
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}Vergiss nicht, die .env in deine .gitignore aufzunehmen, damit keine Geheimnisse im Repository landen.
Fazit
Docker Compose macht aus einem Wirrwarr einzelner Container eine sauber beschriebene Anwendung. In einer einzigen YAML-Datei definierst du Web-App, Datenbank und alles, was dazugehört, und startest es mit docker compose up. Volumes sorgen für dauerhafte Daten, und eine .env-Datei hält deine Geheimnisse aus dem Code heraus. Probiere als Nächstes aus, eines deiner Projekte zusammen mit einer Datenbank in einer compose-Datei zu beschreiben – du wirst die Einfachheit schnell zu schätzen wissen.