Docker Compose mit include übersichtlich in mehrere Dateien aufteilen¶
Veröffentlicht am 8. September 2026 · Geschätzte Lesezeit: 10 Minuten
Mit include bindest du vollständige Compose-Dateien als eigenständige Bausteine in ein Hauptprojekt ein. Compose übernimmt deren Dienste, Netzwerke und Volumes in das gemeinsame Anwendungsmodell; relative Pfade bleiben dabei auf den jeweiligen Baustein bezogen.[1][2] So kannst du einen gewachsenen Stack ordnen, ohne bei jedem Befehl mehrere -f-Optionen anzugeben.[3] Plane etwa 30 bis 45 Minuten für Sicherung, Aufteilung und Funktionsprüfung ein.
Voraussetzungen
- Ein Linux-Server oder NAS mit Docker Engine und dem Docker-Compose-Plugin ab Version 2.20.3
- Ein bereits funktionierendes Compose-Projekt mit einer
compose.yaml - Terminalzugriff auf den Projektordner
- Ein aktuelles Backup der Compose-Datei und aller wichtigen Anwendungsdaten
1. Projekt und Compose-Version prüfen¶
Wechsle in den Ordner deines vorhandenen Compose-Projekts. Ersetze <projektordner> durch dessen vollständigen Pfad:
Zeige die installierte Compose-Version an:
Die aktuelle Docker-Anleitung nennt Docker Compose 2.20.3 oder neuer als Voraussetzung für include.[2] Ist die installierte Version älter oder meldet Docker, dass compose kein gültiger Befehl ist, aktualisiere zuerst das offizielle Docker-Compose-Plugin passend zu deinem Betriebssystem.
Prüfe danach die noch unveränderte Konfiguration:
docker compose config löst die Compose-Dateien und Variablen zum tatsächlichen Anwendungsmodell auf; --quiet prüft nur und unterdrückt die normale Ausgabe. Behebe vorhandene Fehler, bevor du Dateien verschiebst.
Zeige außerdem die definierten Dienste und den aktuellen Containerzustand:
Notiere Dienstnamen, veröffentlichte Ports und den normalen Nutzerzugang. Diese Angaben brauchst du für den Vergleich nach der Umstellung.
2. Konfiguration und Daten sichern¶
Erstelle eine datierte Sicherung des gesamten Projektordners. Wechsle dafür zuerst in dessen übergeordneten Ordner:
Ersetze <projektname> durch den tatsächlichen Namen des Compose-Projektordners:
Wechsle anschließend wieder in das Projekt:
Schreibe zusätzlich das bisher aufgelöste Modell in eine Vergleichsdatei:
<projektname> ist in allen drei Befehlen derselbe vorhandene Ordnername. cp -a erhält Unterordner und Dateiattribute. Die Kopie ist nur dann ein ausreichendes Datenbackup, wenn alle Bind-Mounts innerhalb dieses Projektordners liegen. Sichere Datenbanken, externe Pfade und benannte Volumes zusätzlich mit dem dokumentierten Verfahren der jeweiligen Anwendung.
Keine Volumes löschen
Verwende weder beim Umbau noch beim Rückweg docker compose down -v. Die Option -v entfernt benannte Volumes und kann damit dauerhafte Anwendungsdaten löschen.[9]
3. Geeignete Grenze für den Baustein wählen¶
Lagere eine zusammengehörige, bereits funktionierende Komponente aus, beispielsweise einen Webdienst samt eigenem Konfigurationsordner oder eine Datenbank samt Verwaltungswerkzeug. Eine eingebundene Datei ist keine lose Textvorlage, sondern ein eigenes Compose-Anwendungsmodell. Nach dem Laden kopiert Compose dessen Ressourcen in das Hauptmodell.[1][4]
Für diese Anleitung dient ein kleiner Nginx-Webdienst als ungefährliches Muster. Das Hauptprojekt enthält später einen echten Funktionstest, der den eingebundenen Dienst über seinen Compose-Dienstnamen web aufruft.
Lege die benötigten Unterordner an:
Die geplante Struktur sieht so aus:
<projektordner>/
├── compose.yaml
├── compose-resolved-before.yaml
└── web/
├── compose.yaml
└── html/
└── index.html
<projektordner> steht nur in der Darstellung für deinen vorhandenen Projektordner und wird nicht als Ordner mit spitzen Klammern angelegt. Der Unterordner web ist der eigenständige Baustein; web/html enthält die Testseite.
4. Testinhalt im Baustein anlegen¶
Erstelle eine harmlose HTML-Datei:
Füge folgenden Inhalt ein:
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<title>Compose-Include-Test</title>
</head>
<body>
<h1>Der eingebundene Webdienst funktioniert.</h1>
</body>
</html>
Speichere die Datei und schließe den Editor. Sie enthält keine Zugangsdaten und verändert keine Anwendungsdaten. Im späteren Nginx-Dienst wird der Ordner nur lesbar eingebunden.
<html>, <head>, <meta>, <title>, <body> und <h1> sind feste HTML-Elemente des Beispiels, keine zu ersetzenden Platzhalter. Nur der sichtbare Text zwischen den öffnenden und schließenden Elementen kann nach Wunsch geändert werden.
Wenn du ein vorhandenes Projekt aufteilst, kopierst oder verschiebst du stattdessen die bereits geprüften Konfigurationsdateien des gewählten Dienstes in dessen Unterordner. Ändere beim ersten Umbau möglichst nicht gleichzeitig Image-Versionen, Ports und Anwendungsoptionen.
5. Eigenständige Compose-Datei erstellen¶
Öffne die Compose-Datei des neuen Bausteins:
Füge dieses vollständige Beispiel ein:
services:
web:
image: nginx:1.29-alpine
restart: unless-stopped
ports:
- "127.0.0.1:${WEB_PORT:-8080}:80"
volumes:
- ./html:/usr/share/nginx/html:ro
Die Werte bedeuten:
webist der Compose-Dienstname. Andere Dienste im gemeinsamen Modell erreichen ihn unter diesem Namen.nginx:1.29-alpineist der Beispiel-Image-Tag. Prüfe vor einem produktiven Einsatz, ob er zu deiner Plattform und deiner Aktualisierungsstrategie passt; ersetze ein vorhandenes geprüftes Image nicht unnötig.WEB_PORTist ein optionaler Platzhalter für den Host-Port. Ohne gesetzten Wert verwendet Compose8080.127.0.0.1bindet den Port nur an den Server selbst und stellt ihn nicht im gesamten Heimnetz bereit.80rechts vom Doppelpunkt ist der Port innerhalb des Containers../htmlist absichtlich relativ zur eingebundenen Datei. Compose löst diesen Pfad gegen den Ordnerwebauf, nicht gegen den Ordner der Hauptdatei.[1][2]:robindet den Inhalt nur lesbar ein.
Bei einem bestehenden Dienst übernimmst du dessen bisherigen Image-Tag, Umgebungsvariablen, Netzwerke, Volumes und Sicherheitsoptionen unverändert. Achte darauf, alle zugehörigen relativen Dateien gemeinsam in den Baustein zu verschieben oder die Pfade bewusst anzupassen.
6. Baustein mit include einbinden¶
Sichere die Hauptdatei noch einmal einzeln:
Öffne danach die Hauptdatei:
Trage include auf oberster Ebene ein. Für das vollständige Testprojekt kann die Datei so aussehen:
include:
- web/compose.yaml
services:
smoke-test:
image: curlimages/curl:8.16.0
depends_on:
- web
command:
- --fail
- --silent
- --show-error
- http://web/
profiles:
- test
include steht auf derselben Ebene wie services, nicht innerhalb eines Dienstes.[1][4] web/compose.yaml ist der relative Pfad zur einzubindenden Datei.
Der Dienst smoke-test ruft den eingebundenen Webdienst tatsächlich unter http://web/ auf. curlimages/curl:8.16.0 ist ein Beispiel-Image mit festem Tag; prüfe den Tag vor produktiver Übernahme. Das Profil test verhindert, dass der kurzlebige Prüfcontainer beim normalen docker compose up -d dauerhaft mitgestartet wird. depends_on beschreibt hier die echte Compose-Abhängigkeit vom Dienst web.
In deinem bestehenden Projekt behältst du alle nicht ausgelagerten Dienste unter services:. Entferne einen verschobenen Dienst aus der Hauptdatei, damit sein Ressourcenname nicht doppelt vorkommt. Compose warnt bei Konflikten zwischen eingebundenen und lokalen Ressourcen und versucht nicht, sie stillschweigend zusammenzuführen.[1][4]
7. Aufgelöste Konfiguration vor dem Start prüfen¶
Prüfe zuerst nur die Syntax und das resultierende Modell:
Der Befehl muss ohne Fehlermeldung mit Exit-Code 0 enden. Zeige anschließend die übernommenen Dienste:
Für das Beispiel müssen web und smoke-test erscheinen. Schreibe das neue Modell in eine Datei:
Prüfe den tatsächlich aufgelösten Mount-Pfad:
Die Ausgabe muss beim Quellpfad auf <projektordner>/web/html zeigen. Ersetze <projektordner> beim Lesen gedanklich durch den absoluten Pfad deines Projekts; der Befehl selbst enthält keinen Platzhalter.
Vergleiche bei einem umgebauten Bestandsprojekt die beiden Modelle:
Erwartet werden vor allem Darstellungsunterschiede durch die neue Dateiaufteilung. Unbeabsichtigte Änderungen an Images, Ports, Volumes, Netzwerken oder Umgebungswerten musst du vor dem Start korrigieren.
Aufgelöste Ausgabe vertraulich behandeln
docker compose config kann interpolierte Werte ausgeben. Veröffentliche compose-resolved-before.yaml, compose-resolved-after.yaml oder kopierte Terminalausgaben nicht ungeprüft, weil darin Zugangsdaten oder interne Pfade sichtbar sein können.
8. Fehlende Datei und Ressourcenkonflikt kontrolliert testen¶
Prüfe zunächst, ob ein falscher Include-Pfad verständlich fehlschlägt. Benenne den Baustein nur kurzzeitig um:
Führe die Prüfung aus:
Dieser Aufruf muss wegen der fehlenden Datei fehlschlagen. Stelle den korrekten Namen sofort wieder her:
Prüfe erneut:
Der Aufruf muss jetzt wieder erfolgreich sein. Teste Ressourcenkonflikte nicht auf einem produktiven Stack. Wenn Haupt- und eingebundene Datei denselben Dienst-, Netzwerk- oder Volumenamen definieren, betrachtet Compose das als Konflikt und führt die Definitionen nicht wie bei einer Override-Datei zusammen.[1][2]
include kann zwar weitere include-Abschnitte rekursiv laden, doch mehrere Ebenen erschweren die Fehlersuche. Beginne mit einer flachen Struktur und ergänze weitere Ebenen nur mit klarer Zuständigkeit.[1][2]
9. Dienste starten und Funktion prüfen¶
Starte den normalen Stack im Hintergrund:
Kontrolliere den Zustand:
Zeige die letzten Protokollzeilen des eingebundenen Dienstes:
Teste den lokal gebundenen Port direkt auf dem Server:
Der Befehl muss die Überschrift aus web/html/index.html ausgeben. 8080 ist der Standardwert aus der Compose-Datei. Falls du WEB_PORT gesetzt hast, ersetze 8080 im Prüfaufruf durch den tatsächlich gewählten Host-Port.
Starte danach den im Hauptprojekt definierten internen Funktionstest:
Der Prüfcontainer erreicht web über das gemeinsame Compose-Netzwerk und muss mit Exit-Code 0 enden. --rm entfernt nur diesen kurzlebigen Testcontainer nach dem Lauf. Prüfe bei einer echten Anwendung zusätzlich deren normalen Browser- oder Client-Zugang sowie alle abhängigen Funktionen.
10. Risiken und typische Fehler beheben¶
Beachte beim dauerhaften Einsatz diese Risiken:
- Eingebundene Dateien werden Teil deines resultierenden Compose-Modells. Binde nur lokale oder anderweitig kontrollierte Quellen ein.
- Verwende keine ungeprüften Remote-Git- oder OCI-Quellen für produktive Systeme, auch wenn aktuelle Compose-Versionen solche Quellen unterstützen können.[2]
- Eine übersichtlichere Datei ist kein Sicherheitsmechanismus. Rechte, Secrets, Portbindungen, Image-Updates und Backups bleiben weiterhin nötig.
- Relative Build-, Bind-Mount- und
env_file-Pfade können nach dem Verschieben auf andere Dateien zeigen. Kontrolliere deshalb immer die aufgelöste Ausgabe.[1] - Mehrere Bausteine teilen das resultierende Compose-Modell. Gleich benannte Ressourcen führen zu Konflikten.[1][4]
- Beim ersten
upnach dem Umbau können Container neu erstellt werden. Plane für wichtige Dienste ein Wartungsfenster ein.
Typische Fehler lassen sich so eingrenzen:
Additional property include is not allowed: Die Compose-Version ist zu alt. Prüfedocker compose versionund aktualisiere das Plugin auf eine unterstützte Version.[2]- Datei nicht gefunden: Kontrolliere Schreibweise, Groß-/Kleinschreibung und den Pfad relativ zur Hauptdatei.
- Falscher Datenordner: Prüfe
docker compose config; kurzeinclude-Pfade erhalten für die eingebundene Anwendung ein eigenes Projektverzeichnis.[1] - Ressourcenname ist doppelt: Entferne die alte Definition aus der Hauptdatei oder wähle bewusst einen eindeutigen Namen. Erwarte keine automatische Zusammenführung.[1][4]
- Variable fehlt: Setze sie in der vorgesehenen lokalen Umgebung oder verwende bei verpflichtenden Werten die Compose-Schreibweise
${VARIABLENNAME:?verständliche Fehlermeldung}.[1] - Testcontainer bleibt beendet sichtbar: Verwende den gezeigten Lauf mit
docker compose run --rm smoke-testund kontrolliere bei einem Fehler dessen Ausgabe. - Webseite ist aus dem Heimnetz nicht erreichbar: Die Beispielbindung
127.0.0.1ist absichtlich nur lokal. Öffne keinen Port ungeschützt ins Internet; nutze für Fernzugriff einen bereits abgesicherten Reverse Proxy oder VPN.
Die Praxisanleitung von Keitaro zeigt ebenfalls eine Aufteilung in eigenständige Anwendungs- und Backend-Dateien und verwendet bei Bedarf die lange include-Syntax mit eigenen Umgebungsdateien.[7]
Das öffentlich auffindbare Video „Simplifying Docker Compose with Modularization Using the Include Feature“ demonstriert das Grundprinzip ergänzend.[6]
Für Syntax, Versionsvoraussetzungen und Konfliktverhalten sind die aktuellen Docker-Quellen maßgeblich.[1][2]
11. Rückweg durchführen¶
Stoppe zuerst weitere Tests. Zeige die angelegten Sicherungsdateien an:
Ersetze <sicherungsdatei> durch den vollständigen Dateinamen der gewünschten Sicherung:
<sicherungsdatei> muss eine zuvor angelegte, vertrauenswürdige Sicherung der Hauptdatei sein. Entferne oder verschiebe den neuen Unterordner noch nicht, solange du nicht geprüft hast, ob dort inzwischen Daten liegen.
Prüfe die wiederhergestellte Konfiguration:
Übernimm danach das alte Modell:
Kontrolliere Container und Protokolle:
docker compose down entfernt standardmäßig die für das Projekt erstellten Container und Netzwerke, aber keine externen Ressourcen; mit -v würden zusätzlich benannte Volumes entfernt.[9] Für diesen Rückweg reicht normalerweise docker compose up -d mit der wiederhergestellten Datei. Bei Datenproblemen verwendest du das anwendungsspezifische Backup aus Schritt 2.
Sources¶
[1] https://docs.docker.com/reference/compose-file/include — Docker Docs: include [2] https://docs.docker.com/compose/how-tos/multiple-compose-files/include — Docker Docs: Include multiple Compose files [3] https://www.docker.com/blog/improve-docker-compose-modularity-with-include — Docker Blog: Improve Docker Compose Modularity with include [4] https://github.com/compose-spec/compose-spec/blob/main/14-include.md — Compose Specification: Include [6] https://www.youtube.com/watch?v=GhICKo39eW8 — Video: Simplifying Docker Compose with Modularization Using the Include Feature [7] https://www.keitaro.com/insights/2025/01/13/streamline-docker-compose-with-the-include-directive — Keitaro: Streamline Docker Compose with the Include Directive [9] https://docs.docker.com/reference/cli/docker/compose/down — Docker Docs: docker compose down
Fertig¶
Dein Compose-Projekt besteht jetzt aus einer übersichtlichen Hauptdatei und einem eigenständigen, eingebundenen Baustein. Die Funktionsprüfung ist bestanden, wenn docker compose config --quiet Exit-Code 0 liefert, docker compose config --services die Dienste aus beiden Dateien zeigt, der aufgelöste Mount auf web/html verweist, docker compose up -d den Webdienst startet, der lokale curl-Aufruf die Testseite ausgibt und docker compose run --rm smoke-test erfolgreich endet.[1]