Docker Compose verstehen: Der Einstieg an einem echten Beispiel

Das Wichtigste in Kürze

  • Mit Docker Compose beschreibst du mehrere Container in einer einzigen Textdatei und startest den ganzen Verbund mit einem Befehl: docker compose up -d.
  • Der richtige Aufruf lautet heute docker compose (mit Leerzeichen). Das alte docker-compose mit Bindestrich ist eingestellt.
  • Die Datei heißt bevorzugt compose.yaml. Die früher übliche erste Zeile version: ist überflüssig und sollte raus.
  • Compose ist für einen einzelnen Server gedacht — fürs Homelab ideal, für echte Rechner-Cluster nicht.

Wer im Homelab mehr als einen Container betreibt, kennt das Problem: Für jeden Dienst ein langer docker run-Befehl mit einem Dutzend Schaltern, und beim nächsten Neustart muss man raten, wie er noch mal lautete. Docker Compose löst das. Es ist ein Werkzeug, das mehrere Container als einen Verbund über eine einzige YAML-Datei beschreibt — YAML ist ein schlichtes Textformat, in dem Einrückungen die Struktur vorgeben. Ein Befehl startet oder stoppt danach alles zusammen. Dieser Artikel geht Docker Compose an einem echten Beispiel durch: einer Webanwendung mit eigener Datenbank.

Compose V2: der Stand der Dinge

Die aktuelle Umsetzung heißt Compose V2, ist in Go geschrieben und steckt als Erweiterung direkt in der Docker-Kommandozeile. Daher der Aufruf mit Leerzeichen: docker compose. Die erste Version war ein separates Python-Programm namens docker-compose (mit Bindestrich). Sie ist im Mai 2024 endgültig ausgelaufen und wurde ab April 2025 aus den offiziellen Docker-Images entfernt. Wenn du also irgendwo eine Anleitung mit Bindestrich siehst: veraltet — die Datei selbst funktioniert unverändert weiter.

Separat installieren musst du Compose heute nicht mehr. Auf Linux-Servern kommt es mit dem Paket docker-compose-plugin, in Docker Desktop ist es gebündelt. Für allgemein verfügbar erklärt wurde Compose V2 im Mai 2022.

Die Datei: compose.yaml

Laut Compose-Spezifikation — dem herstellerübergreifenden Standard für das Dateiformat — heißt die Datei bevorzugt compose.yaml, alternativ compose.yml. Die alten Namen docker-compose.yml und .yaml funktionieren aus Kompatibilitätsgründen weiter. Liegen mehrere davon im selben Ordner, nimmt Compose die erste nach fester Reihenfolge: compose.yml, compose.yaml, docker-compose.yml, docker-compose.yaml.

Eine Sache noch: Früher stand oben in jeder Datei eine Zeile wie version: "3.8". In V2 ist dieser Schlüssel funktionslos — Compose prüft immer gegen das aktuelle Schema. Steht die Zeile noch drin, kommt sogar eine Warnung: „the attribute `version` is obsolete, it will be ignored“. Also löschen.

Das Beispiel: Webanwendung mit Datenbank

Hier eine compose.yaml für einen typischen Fall — eine Anwendung app, die eine PostgreSQL-Datenbank db braucht. beispiel/webapp:latest ist ein Platzhalter; dort setzt du das Image deiner Anwendung ein.

services:
  db:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_DB: app
      POSTGRES_USER: app
      POSTGRES_PASSWORD: ${DB_PASSWORT}
    volumes:
      - db-daten:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

  app:
    image: beispiel/webapp:latest
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
    ports:
      - "8080:80"
    volumes:
      - ./app-config:/config
    env_file:
      - .env

volumes:
  db-daten:

Was hier passiert:

  • services: — jeder Eintrag darunter ist ein Container. Hier db und app.
  • image: — die Vorlage, aus der der Container entsteht. Compose lädt sie bei Bedarf aus einer Registry wie Docker Hub.
  • ports: — "8080:80" macht Port 80 im Container von außen unter Port 8080 erreichbar. Wichtig seit Docker Engine 28 (Februar 2025): Aus dem restlichen Heimnetz sind Container standardmäßig nur noch über solche veröffentlichten Ports erreichbar, nicht mehr über die interne Container-IP.
  • environment: — Konfiguration, die die Anwendung als Umgebungsvariable erwartet. ${DB_PASSWORT} wird aus der .env-Datei eingesetzt.
  • volumes: — dauerhafter Speicher, damit Daten einen Neustart überleben. Zwei Arten, siehe Tabelle weiter unten.
  • restart: — Neustart-Regel. unless-stopped heißt: nach Absturz oder Server-Neustart automatisch wieder hoch, außer du hast den Container von Hand gestoppt.

.env für Passwörter und Pfade

Neben die compose.yaml legst du eine Datei namens .env:

DB_PASSWORT=hier-ein-langes-passwort

Diese Datei füllt die Platzhalter in der Compose-Datei selbst (die ${...}-Stellen) und wird über env_file: zusätzlich in den Container gereicht. So bleiben Geheimnisse aus der eigentlichen Konfiguration heraus — praktisch, wenn du die compose.yaml mal in einem Git-Repository ablegst. Alternativ trägst du Werte direkt unter environment: ein.

restart, depends_on und healthcheck: bis es wirklich läuft

Ein verbreiteter Irrtum: depends_on sorge dafür, dass die Datenbank fertig hochgefahren ist, bevor die App startet. Tut es nicht. In der Kurzform wartet Compose nur, bis der Datenbank-Prozess gestartet ist — nicht, bis die Datenbank Verbindungen annimmt. Die App läuft dann oft in einen Fehler.

Die Lösung steht im Beispiel: ein healthcheck an der Datenbank plus condition: service_healthy beim depends_on. Der healthcheck führt in Intervallen einen Testbefehl aus (test); nach retries Fehlversuchen gilt der Container als „unhealthy“. Die Felder sind test, interval, timeout, retries und start_period (eine Anlaufzeit, in der Fehlschläge noch nicht zählen). Erst wenn der Check besteht, startet Compose die abhängige app. Ist die Datenbank dauerhaft unhealthy, startet app gar nicht.

Noch ein Missverständnis: Einen unhealthy oder abgestürzten Container startet Docker nicht von selbst neu. Dafür braucht es eine Restart-Regel. Die Optionen: no (Standard), always, on-failure (optional mit Obergrenze, etwa on-failure:5) und unless-stopped.

Bind Mount oder Named Volume?

Beide sorgen für dauerhaften Speicher, werden aber unterschiedlich verwaltet — das betrifft auch dein Backup und das Verhalten bei Dateirechten.

  Bind Mount Named Volume
Schreibweise ./app-config:/config db-daten:/var/lib/… plus Eintrag unter volumes:
Wo liegen die Daten? An einem Pfad, den du selbst wählst (Host-Ordner) Von Docker verwaltet unter /var/lib/docker/volumes/
Backup Ordner sichern wie jeden anderen Über Docker oder den Volume-Pfad
Gut für Konfigurationsdateien, die du direkt bearbeiten willst Datenbankdateien und Ähnliches, wo Docker die Rechte regeln soll

Die wichtigsten Befehle

  • docker compose up -d — Verbund im Hintergrund starten.
  • docker compose down — Container und Netzwerke stoppen und entfernen. Benannte Volumes bleiben erhalten; deine Daten sind also nicht weg.
  • docker compose down -v — zusätzlich die benannten Volumes löschen. Das entfernt die Daten. Mit Bedacht.
  • docker compose pull — neue Image-Versionen holen.
  • docker compose up -d --build — Images neu bauen (falls du selbst eins baust) und starten.
  • docker compose up --watch bzw. docker compose watch — Dateiänderungen live in den laufenden Container spiegeln, konfiguriert im Abschnitt develop: → watch:. Eingeführt in Compose v2.22.0 (September 2023), eher für die Entwicklung als für den Dauerbetrieb gedacht.

Wo läuft das im Homelab?

Auf einem Linux-Server oder NAS (Network Attached Storage, also ein Speicher, der am Netzwerk hängt) brauchst du kein Docker Desktop — das ist ein GUI-Paket für Windows- und Mac-Desktops, und nur dort stellt sich überhaupt die Lizenzfrage für größere Firmen. Auf dem Server genügen Docker Engine und das Compose-Plugin.

  • Synology: Seit DSM 7.2 (Mai 2023) heißt das Paket Container Manager (vorher „Docker“). Der Tab „Projekt“ führt Compose-Dateien direkt aus der Oberfläche aus; bestehende Container werden übernommen.
  • QNAP: Container Station 3 nutzt Compose V2 und braucht QTS 5.1 oder neuer.
  • Unraid: Compose ist nicht eingebaut; es kommt über das Community-Plugin „Compose Manager Plus“.
  • GUI drüber: Portainer verwaltet Compose-Verbünde als „Stacks“; Dockge ist eine schlanke Oberfläche speziell dafür, bei der die YAML-Datei sichtbar auf der Platte liegen bleibt.
Unsere Empfehlung

UGREEN NASync DXP4800 Plus 4 Bay NAS für Familien und Teams (ohne HDD)

UGREEN NASync DXP4800 Plus 4 Bay NAS für Familien und Teams (ohne HDD)
Ein Vier-Schacht-NAS gibt deinen Docker-Compose-Stacks ein festes Zuhause im Heimnetz, das durchläuft, ohne dass ein PC anbleiben muss. Preis: 599,99 € (Stand 31.08.2026).

Preis prüfen *

Was Compose nicht ist

Compose zielt auf einen einzelnen Host. Willst du Container über mehrere Server verteilen, brauchst du andere Werkzeuge — Docker Swarm, Kubernetes oder Multi-Host-Verwaltungen wie Komodo. Fürs klassische Homelab mit einem Server oder NAS ist das kein Nachteil, sondern genau der Zweck.

Der schnellste Einstieg: eine compose.yaml mit einem einzigen Dienst anlegen, docker compose up -d, dann die Logs mit docker compose logs -f ansehen. Danach den zweiten Dienst dazu. So wächst dein Setup Stück für Stück — und ist jederzeit in einer Textdatei nachlesbar.

Mit * markierte Links sind Affiliate-Links. Kaufst du darüber, bekommen wir eine Provision — für dich ändert sich der Preis nicht.

Leave a Comment

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

© 2026 Homelab Helden
Scroll to Top