Docker Compose: Befehle für Server im Überblick
Die wichtigsten Compose-V2-Befehle für Start, Änderungen, Logs, Shells, Netzwerke, Volumes und sicheres Aufräumen, inklusive typischer Fehlermeldungen.
Die Compose-Befehle, die Sie tatsächlich benötigen
Docker Compose bietet Dutzende Unterbefehle. Im täglichen Serverbetrieb werden etwa ein Dutzend davon verwendet. Diese Seite gruppiert diese nach ihrem Einsatzzweck, nennt einen einfachen Grund für jeden Befehl und verweist auf weiterführende Informationen, falls ein Befehl eine Falle birgt.
Alles hier bezieht sich auf Compose V2 oder V5: docker compose mit einem Leerzeichen, nicht das alte docker-compose-Skript. Beide sind Go-Plugins; unter Linux wird das Compose-Plugin separat von der Docker Engine installiert. Ubuntu 24.04 LTS bietet das veraltete Python-V1-Tool weiterhin als docker-compose in der Version 1.29.2-6ubuntu1 im Universe-Repository an. Überprüfen Sie dies mit docker compose version. Falls der Befehl nicht verfügbar ist, richten Sie das Docker-Repository ein und installieren Sie das Paket docker-compose-plugin.
Jeder der folgenden Befehle wird aus dem Verzeichnis ausgeführt, das Ihre compose.yaml enthält; Compose verwendet den Namen dieses Verzeichnisses als Standard-Projektname, sofern Sie diesen nicht überschreiben. Ohne -f oder COMPOSE_FILE durchsucht Compose das aktuelle Arbeitsverzeichnis und dessen übergeordnete Verzeichnisse nach einer Konfigurationsdatei. Wenn Sie den Befehl eine Ebene höher ausführen, wird Ihr Stack nur gefunden, wenn sich die Datei noch innerhalb dieses Suchpfads befindet. Falls Ihnen das Dateiformat selbst noch nicht vertraut ist, beginnen Sie mit einer ersten Compose-Datei auf einem VPS und kehren Sie für die Befehle hierher zurück.
Lifecycle: die vier Befehle, die Sie eingeben, und der eine, der Container entfernt
docker compose up -d
docker compose up -d --wait
docker compose stop
docker compose start
docker compose restart web
docker compose downup -d erstellt das Netzwerk, erstellt die Container, startet sie und kehrt zum Prompt zurück. Da der Befehl nach dem Start der Container zurückkehrt, ohne die Betriebsbereitschaft der Anwendung abzuwarten, schlägt ein nachfolgendes Deploy-Skript mit einem curl-Probe oft beim ersten Versuch fehl. up -d --wait wartet darauf, dass Dienste mit Healthchecks den Status „healthy“ erreichen und Dienste ohne Healthchecks laufen; ein nicht fehlerfreier Dienst oder ein abgelaufener --wait-timeout führt zu einem Exit-Code ungleich null. Das Flag ist nur so zuverlässig wie der zugrunde liegende Check. Erstellen Sie daher einen Healthcheck, dem Compose vertrauen kann, bevor Sie sich in der Automatisierung darauf verlassen.
stop hält die Container an und behält sie bei, sodass start dieselben Container mit derselben beschreibbaren Ebene wieder startet. down stoppt die Container und entfernt anschließend sowohl diese als auch das Projektnetzwerk. Alles, was innerhalb des Containers und außerhalb eines Volumes geschrieben wurde, geht dabei verloren. Dies ist das folgenschwerste Missverständnis in Compose, und der vollständige Unterschied zwischen down und stop erläutert, wo dies zu Problemen führt.
restart ist kein Reload. Der Befehl stoppt und startet denselben Container mit der bereits vorhandenen Konfiguration. Eine geänderte Umgebungsvariable, ein neuer Image-Tag oder ein bearbeitetes Port-Mapping haben daher keinerlei Auswirkungen. Um eine Dateiänderung anzuwenden, führen Sie up -d erneut aus. Compose vergleicht jeden Dienst mit seinem laufenden Container und erstellt diejenigen neu, deren Konfiguration oder Image sich geändert hat.
Anwenden einer Änderung: Neuerstellen, Pull oder Rebuild
docker compose up -d --force-recreate
docker compose pull && docker compose up -d
docker compose build --no-cache web
docker compose up -d --build webup -d verwendet laufende Container wieder, wenn deren Konfiguration und Image unverändert sind; Image-Pulls und Builds folgen der Pull-Richtlinie des Dienstes. --force-recreate überschreibt diesen Vergleich und ersetzt jeden Container, selbst wenn die Konfiguration identisch ist. Dies ist der schnellste Weg, um einen fehlerhaften Zustand innerhalb eines Containers zu bereinigen.
Die explizite Routine zur Aktualisierung von Images verwendet zwei Befehle, da diese unterschiedliche Aufgaben erfüllen. pull lädt das aktuelle Image für jeden in der Datei genannten Tag herunter. up -d erkennt daraufhin, dass die Image-ID des Dienstes nicht mehr mit dem laufenden Container übereinstimmt, und erstellt diesen neu. Bei der standardmäßigen Pull-Richtlinie missing werden zwischengespeicherte Tags wiederverwendet, mit Ausnahme von latest, das immer neu geladen wird. Das gegenteilige Risiko zeigt sich bei einem Stack mit mehreren Diensten: Das gleichzeitige Ausführen von latest für alle Dienste kann eine Anwendung unterbrechen, die zehn Sekunden zuvor noch funktionierte. Aus diesem Grund empfiehlt ein selbst gehosteter AFFiNE-Workspace, die Anwendung und das Migrations-Image stattdessen auf denselben Digest festzulegen. Durch das Festlegen (Pinning) wird ein Upgrade zu einer bewussten Änderung des Tags, gefolgt von demselben Pull- und Neuerstellungsvorgang. Bei einem Stack, der seine Datenbank beim Start migriert, sollten Sie vor beiden Befehlen einen Dump erstellen; dies ist die Routine, der ein selbst gehosteter Chatwoot-Support-Desk bei jedem Versionssprung folgt.
build gilt für Dienste, die einen Abschnitt build: deklarieren, einschließlich Diensten, die zusätzlich ein image: angeben. up -d --build baut und startet in einem Schritt; dies ist die übliche Schleife während der Code-Entwicklung. Verwenden Sie --no-cache nur, wenn ein zwischengespeicherter Layer offensichtlich veraltet ist, da hierbei jeder Layer von Grund auf neu erstellt wird. Einige Projekte bieten beide Wege aus einem geklonten Repository an; in diesem Fall sind die beiden Schleifen alternative Update-Pfade: ein selbst gehosteter openGym-Workout-Tracker verwendet docker compose up -d --build, um seinen festgelegten Checkout zu bauen, da das Laden seiner latest-Images eine neuere Version als der aktuelle Checkout installieren könnte.
Überprüfung der laufenden Dienste
docker compose ps
docker compose ps -a
docker compose logs -f --tail=100
docker compose logs --since 15m --timestamps db
docker compose top
docker compose lsps listet nur laufende Container auf. Ein Dienst, der während des Starts abgestürzt ist, bleibt dort unsichtbar, bis Sie -a hinzufügen. Wenn ein Container in ps fehlt, während ps -a ihn als Exited (1) anzeigt, ist dies das typische Anzeichen für einen Startfehler. Lesen Sie den Exit-Code und anschließend die Logs.
logs -f verfolgt alle Dienste gleichzeitig und stellt jeder Zeile den Dienstnamen voran. Dies ist die Ansicht, die Sie benötigen, wenn Dienste miteinander kommunizieren und die Reihenfolge der Ereignisse wichtig ist. Geben Sie einen Dienstnamen an, um die Ausgabe einzugrenzen. --tail=100 ist bei einem Container wichtig, der bereits seit einem Monat läuft, da die Standardeinstellung den gesamten Verlauf ausgibt und das Terminal überflutet. --since 15m beantwortet die Frage, die Sie normalerweise haben: Was ist während des Neustarts passiert, den Sie gerade durchgeführt haben?
top listet die Prozesse innerhalb jedes Containers auf. Dies unterscheidet den Status "Container läuft" von "Prozess im Container läuft". ls wechselt aus dem aktuellen Verzeichnis heraus und listet laufende Compose-Projekte auf dem Host mit ihrem Status auf; fügen Sie -a hinzu, um auch gestoppte Projekte einzubeziehen.
Eine Shell in einem Dienst erhalten
docker compose exec web sh
docker compose exec -u root web sh
docker compose run --rm web env
docker compose run --rm --no-deps web shexec führt einen Befehl in einem bereits laufenden Container aus. run startet einen neuen Container basierend auf derselben Dienstdefinition; dies ist erforderlich, wenn der Dienst nicht lange genug läuft, um ein exec durchzuführen. Kombinieren Sie run immer mit --rm, da sonst jeder Aufruf einen gestoppten Container hinterlässt. Diese sammeln sich an, bis docker compose ps -a unleserlich wird.
Versuchen Sie sh vor bash. Einige Alpine-basierte Images enthalten bash, einschließlich des offiziellen PostgreSQL-Alpine-Images; wenn es fehlt, lautet die Fehlermeldung exec: "bash": executable file not found in $PATH. Das Hinzufügen von --no-deps zu run überspringt die Abhängigkeiten des Dienstes. Dies verhindert, dass eine schnelle Konfigurationsprüfung Ihre gesamte Datenbank startet.
run --rm web env ist der schnellste Weg, um die Umgebung zu sehen, die ein Dienst tatsächlich erhalten hat, nachdem jede .env-Datei, jeder environment:-Block und jede Shell-Variable zusammengeführt wurden. Wenn ein Wert falsch ist, liegt dies meist an der Zusammenführungsreihenfolge, und wie Compose Env-Dateien und Secrets auflöst legt dar, welche Quelle Vorrang hat.
Netzwerke, Ports und Namensauflösung
docker compose port web 80
docker compose exec web getent hosts db
docker compose config --networksStandardmäßig weist Compose jedem Dienst ein Projektnetzwerk zu, wobei jeder Dienstname als DNS-Name innerhalb dieses Netzwerks fungiert. Die Ausführung von getent hosts db innerhalb von web, sofern das Image getent enthält, überprüft die Namensauflösung; es testet jedoch nicht, ob db Verbindungen akzeptiert. Wenn der Name aufgelöst wird, die Verbindung aber abgelehnt wird, prüfen Sie, ob der Server läuft und auf der angeforderten Adresse sowie dem Port lauscht. Eine Bindung an lediglich 127.0.0.1 ist eine mögliche Ursache. Dieselbe Grenze erklärt, warum ein Container, der außerhalb des Projekts gestartet wurde – sei es durch docker run oder als eigener Stack –, ein gemeinsames Netzwerk benötigt, um einen Dienstnamen wie jellyfin aufzulösen. Dies ist der erste Punkt, den Sie prüfen sollten, wenn ein Halcyon-Frontend für Ihre Jellyfin-Mediathek den konfigurierten Server nicht erreichen kann. Das zugrunde liegende Modell wird unter Funktionsweise von Compose-Netzwerken und Dienst-DNS erläutert.
port web 80 gibt die Host-Adresse und den Port aus, unter denen ein Container-Port veröffentlicht wird. Dies erspart das Rätselraten, wenn das Mapping aus einer Variablen stammt. Das Veröffentlichen eines Ports erstellt zudem eine Firewall-Regel, die Docker eigenständig verwaltet. Diese Regel steht vor Ihren eigenen Regeln, sodass ein Dienst, den Sie für privat hielten, möglicherweise aus dem Internet erreichbar ist. Dieser Fall wird unter warum veröffentlichte Docker-Ports ufw umgehen behandelt. Es ist sicherer, diese Ports nicht zu veröffentlichen und stattdessen einen authentifizierenden Proxy im Projektnetzwerk vor die Dienste zu schalten, wie es unter Betrieb von Authentik als Single-Sign-On-Schicht beschrieben wird.
Volumes und Daten
docker compose config --volumes
docker compose cp db:/etc/postgresql/pg_hba.conf ./pg_hba.conf
docker compose down -vconfig --volumes listet die im Projekt deklarierten benannten Volumes auf, eines pro Zeile. Diese Liste ist nur ein Teil eines Backup-Inventars: Auch Bind-Mounts und Konfigurationsdateien müssen geprüft werden. Wenn die Volumes unersetzliche Daten enthalten, ist der exakte Backup-Befehl genauso wichtig wie die Liste. Deshalb erläutert der Vergleich zwischen PhotoPrism und Immich die Dump- und Kopierbefehle, die jeder Fotoserver benötigt. cp kopiert eine Datei in einen Container hinein oder aus ihm heraus, ohne eine Shell zu öffnen; dabei wird die Form service:path auf der Seite verwendet, auf der sich der Container befindet.
down -v entfernt deklarierte benannte Volumes mit Ausnahme externer Volumes sowie anonyme Volumes, die an die Container angehängt sind, zusammen mit den Containern selbst. Dies ist der richtige Befehl zum Abbau eines Test-Stacks, aber der falsche für alles, was wichtige Daten enthält, da es keine Bestätigung und kein Rückgängigmachen gibt. Bind-Mounts überstehen diesen Vorgang, da sie sich im Dateisystem des Hosts befinden. Dieser Unterschied im Wirkungsbereich ist ein Grund, sich bewusst zwischen Bind-Mounts und benannten Volumes zu entscheiden.
Bereinigung zur Speicherplatzfreigabe ohne Datenverlust
docker compose down --remove-orphans
docker system df
docker image prune -a
docker builder prune--remove-orphans löscht Container, die zum Projekt gehören, aber nicht mehr in der Datei aufgeführt sind. Dies ist genau das Verhalten, das nach dem Umbenennen eines Dienstes auftritt. Ohne diesen Befehl laufen diese Container weiter, und docker compose ps schließt verwaiste, laufende Container standardmäßig ein.
docker system df zeigt an, wo der Speicherplatz belegt ist, bevor Sie etwas löschen. Es unterteilt den Speicherbedarf in Images, Container, lokale Volumes und Build-Cache, jeweils mit einem Wert für den zurückgewinnbaren Speicherplatz. image prune -a entfernt jedes Image, das von keinem Container verwendet wird, unabhängig davon, ob es getaggt ist oder nicht. Auf einem System, das mehrere Versionen eines großen Images geladen hat, bringt dies meist den größten Gewinn. builder prune entfernt standardmäßig verwaisten Build-Cache; fügen Sie -a hinzu, um den gesamten ungenutzten Build-Cache zu entfernen.
Keiner dieser Befehle greift auf benannte Volumes zu. docker volume prune --all, docker compose down -v und docker volume rm entfernen benannte Volumes. Ein einfaches docker volume prune entfernt nur anonyme Volumes.
Die Datei prüfen, bevor sie Probleme verursacht
docker compose config --quiet
docker compose config --services
docker compose --dry-run up -dconfig --quiet validiert die Datei und gibt bei Erfolg nichts aus. Daher gehört der Befehl in einen Pre-Deploy-Schritt oder Git-Hook. Das einfache config gibt die vollständig zusammengeführte und interpolierte Datei aus. Damit prüfen Sie, ob eine Variable aufgelöst wurde und eine Override-Datei wie erwartet eingebunden ist. Eine nicht gesetzte Variable erscheint dort als leerer Wert, zusammen mit der Warnung The "X" variable is not set. Defaulting to a blank string.
--dry-run ist ein globales Flag und kein Flag des Subcommands. Daher steht es vor up. Der Befehl gibt jede Aktion aus, die Compose ausführen würde, und nimmt keine Änderungen vor. Diese 30 Sekunden sind vor einem down auf einem wichtigen Stack gut investiert.
Arbeiten mit Dateien, Profilen und Projekten
docker compose -f compose.yaml -f compose.prod.yaml up -d
docker compose --profile debug up -d
docker compose -p staging up -dMehrere -f-Flags werden in der angegebenen Reihenfolge zusammengeführt, wobei spätere Dateien frühere Schlüssel für Schlüssel überschreiben. Dies ist der Standardweg, um eine Basisdatei mit einer kleinen produktiven Anpassung zu pflegen. Da die Regeln für Listen und Maps jedoch abweichen, lesen Sie wie Compose mehrere Dateien zusammenführt, bevor Sie unerwartetes Verhalten untersuchen.
--profile startet Dienste, die mit diesem Profil markiert sind, zusammen mit den nicht markierten Diensten. Dies hält Debug-Werkzeuge aus einem normalen up fern. -p legt den Projektnamen fest, sodass zwei Kopien desselben Stacks mit separaten Netzwerken und separaten Volume-Namen parallel laufen können. Um den Stack nach einem Neustart wiederherzustellen, verwenden Sie eine Restart-Policy oder eine Unit, die Compose für Sie ausführt, wie unter Starten von Compose-Stacks beim Booten beschrieben.
FAQ
Was hat docker-compose durch einen Bindestrich ersetzt?
Compose V2 und V5, aufgerufen als docker compose mit einem Leerzeichen. Unter Linux ist Compose ein separat installiertes Plugin; Ubuntu 24.04 LTS bietet in seinem Universe-Repository weiterhin das Python-Tool V1 an. Wenn die Form mit Leerzeichen nicht verfügbar ist, richten Sie das Docker-Repository ein und installieren Sie das Paket docker-compose-plugin. Aktualisieren Sie alte Skripte auf die Form mit Leerzeichen, anstatt einen Alias zu erstellen, da V2 Flags besitzt, die V1 nicht hatte.
Warum übernimmt docker compose restart meine Konfigurationsänderung nicht?
restart stoppt und startet den existierenden Container mit der Konfiguration, mit der er erstellt wurde, und liest compose.yaml niemals neu ein. Jede Änderung an Umgebungsvariablen, Ports, Volumes oder dem Image-Tag erfordert docker compose up -d, was jeden Dienst mit seinem laufenden Container vergleicht und die abweichenden Container neu erstellt. Fügen Sie --force-recreate hinzu, wenn der Austausch erzwungen werden soll, obwohl sich in der Datei nichts geändert hat.
Wie aktualisiere ich einen Dienst auf ein neueres Image?
Führen Sie docker compose pull aus, gefolgt von docker compose up -d. Der Pull-Befehl lädt das aktuelle Image für jeden Tag in der Datei herunter, und up -d erstellt jeden Dienst neu, dessen Image-ID nicht mehr mit seinem Container übereinstimmt. Die alleinige Ausführung von up -d folgt der Pull-Richtlinie: Die Standardrichtlinie missing verwendet zwischengespeicherte Images wieder, außer bei latest, das immer neu geladen wird.
Welche Aufräumbefehle sind auf einem Live-Server sicher?
docker system df meldet die Festplattennutzung, ohne etwas zu löschen; docker image prune -a und docker builder prune entfernen ungenutzte Images und den Build-Cache, sodass laufende Dienste weiter funktionieren und benannte Volumes unangetastet bleiben. Das gefährliche Paar ist docker compose down -v, das die im Projekt deklarierten, nicht-externen benannten Volumes sowie angehängte anonyme Volumes ohne Rückfrage löscht, und docker volume prune --all, das ungenutzte lokale Volumes (einschließlich benannter) nach einer einzigen j/N-Abfrage oder ohne Abfrage mit -f löscht. Führen Sie zuerst docker compose config --volumes aus, damit Sie wissen, was gefährdet ist.
Kann ich einen einzelnen Befehl ausführen, ohne den gesamten Stack zu starten?
Ja. docker compose run --rm --no-deps web sh startet einen einzelnen Container aus der Dienstdefinition web, überspringt dessen Abhängigkeiten und entfernt den Container, sobald Sie ihn beenden. Verwenden Sie stattdessen exec, wenn der Container bereits läuft, da exec Ihren Befehl innerhalb des laufenden Containers ausführt und Ihnen den tatsächlichen Zustand des Dienstes anzeigt.