Mit Docker Compose können Sie mehrere Docker-Container und die zugehörigen Ressourcen wie Volumes und Netzwerke verwalten. Sie schreiben deklarative YAML-Dateien, die Compose verwendet, um Ihren Container-Stack zu erstellen.
Ihre docker-compose.yml
Dateien können sich wiederholen, wenn Sie mit einem komplexen Stapel arbeiten. Dienste teilen möglicherweise Konfigurationsoptionen, was dazu führt, dass Sie Abschnitte Ihrer Datei duplizieren. Spätere Aktualisierungen können zu Fehlern führen, wenn Sie vergessen, jede Instanz eines Abschnitts zu aktualisieren.
Da Compose-Dateien einfache YAML-Dateien sind, können Sie integrierte YAML-Funktionen nutzen, um Ihre Stack-Definitionen zu modularisieren. Mit Ankern, Aliasen und Erweiterungen können Sie YAML-Abschnitte in wiederverwendbare Blöcke abstrahieren. Sie können an jeder erforderlichen Stelle einen Verweis auf den Abschnitt hinzufügen.
Was ist ein Anker?
YAML-Anker sind eine Funktion, mit der Sie ein Element identifizieren und dann an anderer Stelle in Ihrer Datei darauf verweisen können. Anker werden mit &
erstellt Schild. Dem Vorzeichen folgt ein Aliasname. Sie können diesen Alias später verwenden, um auf den Wert nach dem Anker zu verweisen.
So könnten Sie einen Anker verwenden, um die Wiederholung von Container-Neustartrichtlinien zu vermeiden:
services: httpd: image: httpd:latest restart: &restartpolicy unless-stopped mysql: image: mysql:latest restart: *restartpolicy
Der Anker wird mit *
referenziert Charakter und sein Alias. Achten Sie darauf, dass zwischen &
kein Leerzeichen steht /*
Zeichen und den folgenden Aliasnamen.
Dieses Beispiel zeigt, wie ein einzeiliger Wert mit Ankern wiederverwendet werden kann. Das Ändern der Stack-Neustartrichtlinie kann jetzt an einem Ort vorgenommen werden, ohne die Dienste einzeln zu bearbeiten.
Mehrzeilige Anker
Anker können mehrzeilige Werte haben. Sie erstellen sie mit der gleichen Syntax wie ein einzeiliger Anker. Dies ist nützlich, wenn Sie eine Reihe von Konfigurationsdetails für mehrere Dienste bereitstellen müssen.
services: first: image: my-image:latest environment: &env - CONFIG_KEY - EXAMPLE_KEY - DEMO_VAR second: image: another-image:latest environment: *env
Die second
Der Dienst zieht jetzt dieselben Umgebungsvariablen wie first
. Wir mussten die Liste der Umgebungsvariablen nicht wiederholen, wodurch sie in Zukunft viel besser wartbar ist.
Ankerwerte erweitern
Das obige Umgebungsbeispiel übernimmt den Wert des Ankers und verwendet ihn unverändert. Häufig möchten Sie den Anker erweitern, um zusätzliche Werte hinzuzufügen. Sie können dies mit einer alternativen Syntax tun.
Ändern Sie die second
Service wie folgt:
services: second: image: another-image:latest environment: <<: *env - AN_EXTRA_KEY - SECOND_SPECIFIC_KEY
Der Dienst ruft jetzt die Basisumgebungskonfiguration aus env
ab Anker. Der Umgebungsliste werden dann zusätzliche Schlüssel hinzugefügt. Sie können auch vorhandene Schlüssel überschreiben, die durch den Anker definiert sind.
Erweiterungsfelder verwenden
Ein weiterer Ansatz zur Modularisierung sind Erweiterungsfelder. Dies sind spezielle YAML-Fragmente der obersten Ebene, die von Docker ignoriert werden.
Docker versucht normalerweise, jeden Knoten im Stammverzeichnis einer Compose-Datei zu interpretieren. Der Parser ignoriert Erweiterungsfelder mit dem Präfix x-
. Sie können diese Felder verwenden, um die gemeinsam genutzte Konfiguration zur späteren Referenz zu kapseln. Kombinieren Sie Erweiterungsfelder mit Ankern, um Abschnitte aus Ihren Dienstdefinitionen zu abstrahieren.
x-env: &env environment: - CONFIG_KEY - EXAMPLE_KEY services: first: <<: *env image: my-image:latest second: <<: *env image: another-image:latest
Diese Compose-Datei ist eine weitere Verfeinerung gegenüber dem oben gezeigten Beispiel. Die Umgebungsvariablen gehören keinem der Dienste mehr an. Sie wurden vollständig herausgehoben, in die x-env
Erweiterungsfeld.
Dies definiert einen neuen Knoten, der die environment
enthält Feld. Es wird ein YAML-Anker verwendet (&env
), sodass beide Dienste auf den Wert des Erweiterungsfelds verweisen können.
Zusammensetzbarkeit
Wenn Sie diese Funktionen nutzen, können Sie Ihre Compose-Dateien in eigenständige Teile aufteilen. Dies hilft Ihnen, sich übermäßig wiederholende Dienstdefinitionen zu vermeiden. Alles, was mehr als einem Dienst gemeinsam ist, sollte in ein Erweiterungsfeld aufgenommen werden.
Neben der Unterstützung der Wartbarkeit teilt diese Vorgehensweise Ihre Absichten anderen Mitarbeitern mit. Es ist klar, dass alle Erweiterungsfelder der obersten Ebene generische Felder enthalten. Sie sind nicht an einen bestimmten Dienst gebunden und können frei wiederverwendet werden.
Anker und Erweiterungsfelder lassen Sie komponieren Ihre Dienstdefinitionen aus wiederverwendbaren Blöcken von YAML. Indem Sie jedes Feld klein halten, können Ihre Dienste Konfigurationsabschnitte aus den verfügbaren Ankern mischen und anpassen. Die Pflege Ihrer Compose-Dateien sollte weniger lästig werden.
Andere Ansätze zur Modularität
Vergessen Sie nicht, neben Ankern und Erweiterungen, dass Sie Ihre Compose-Definitionen jederzeit in mehrere Compose-Dateien aufteilen können. Dies kann erforderlich werden, wenn Sie mehr als eine Handvoll einzelner Dienste haben.
Durch die Verwendung mehrerer Compose-Dateien können Sie jedem Dienst eine eigene Datei zuweisen. Sie können auch Überschreibungsdateien erstellen, in denen die Werte eines Knotens ersetzt oder erweitert werden. Compose fügt alle Dateien zusammen, um die endgültige Laufzeitkonfiguration zu erstellen.
service.yml
services: service: image: my-image:latest
service-dev.yml
services: service: environment: - DEV_MODE=true
In diesem Beispiel würde die Anwendung beider Compose-Dateien zu einem Dienst führen, my-image:latest
, mit dem DEV_MODE
Umgebungsvariable gesetzt. Um mehrere Dateien mit der Compose-CLI zu verwenden, übergeben Sie -f
Flagge:
docker-compose -f service.yml -f service-dev.yml up -d
Dateien werden in der angegebenen Reihenfolge zusammengeführt.
Zusammenfassung
Docker Compose-Dateien können unhandlich und repetitiv werden. Wenn Sie Zeit damit verbringen, Werte zu kopieren, sollten Sie erwägen, Abschnitte Ihrer Dienste in dedizierte YAML-Blöcke zu abstrahieren.
Funktionen wie Anker und Erweiterungen unterstützen die Wartbarkeit und erleichtern das Authoring-Erlebnis. Nicht jede Compose-Datei wird davon profitieren – einige Dienste haben möglicherweise wenig gemeinsam – also prüfen Sie Ihren spezifischen Stack, bevor Sie beginnen.