Docker Compose YAML Anchors und Aliases fuer DRY Konfiguration
AI generated
FROM
RUN
Docker · Docker Compose · YAML · Konfiguration
YAML Anchors und Aliases
DRY Konfiguration in Docker Compose

Sobald eine compose.yaml mehr als drei oder vier Services enthaelt, wiederholen sich Logging-Konfiguration, Umgebungsvariablen und Healthcheck-Definitionen fast identisch in jedem Block. YAML Anchors, Aliases und Merge Keys erlauben es, diese Bloecke einmal zu definieren und ueberall wiederzuverwenden, ohne dass Docker Compose selbst dafuer eine eigene Funktion braucht.

16 Min. Lesezeit Anchors · Aliases · Merge Keys · Extension Fields Docker Compose 2.x

1. Warum Wiederholung in compose.yaml zum Problem wird

Je mehr Services eine Docker Compose Datei enthaelt, desto staerker wiederholen sich bestimmte Bloecke. Logging-Treiber, Restart-Policies, Healthcheck-Definitionen und ganze Umgebungsvariablen-Listen tauchen in nahezu jedem Service identisch oder fast identisch wieder auf. Wird eine Einstellung geaendert, etwa die maximale Logdatei-Groesse, muss dieselbe Aenderung an fuenf, zehn oder mehr Stellen wiederholt werden, was Fehler begĂĽnstigt und Reviews erschwert.

Genau hier setzen YAML Anchors und Aliases an. YAML als Format hinter jeder compose.yaml unterstuetzt seit langem eine eigene Referenzierungssyntax, mit der ein Block einmal definiert und an beliebig vielen Stellen im Dokument wiederverwendet werden kann. Docker Compose selbst muss dafuer keine eigene Funktion mitbringen, weil die Anker- und Alias-Syntax bereits Teil der YAML-Spezifikation ist und von jedem konformen YAML-Parser verstanden wird, inklusive dem, den Docker Compose intern verwendet.

Der Vorteil gegenueber reiner Wiederholung ist offensichtlich: Aenderungen an einer zentralen Stelle wirken sich automatisch auf alle Services aus, die den entsprechenden Anker referenzieren. Das reduziert nicht nur die Dateigroesse, sondern vor allem das Risiko, dass ein Service beim manuellen Kopieren vergessen oder falsch angepasst wird. Fuer Teams mit mehreren Microservices oder einem Magento-Stack mit PHP-FPM, Nginx, Node und mehreren Datenbanken ist das ein direkter Wartbarkeitsgewinn.

2. YAML Anchors und Aliases: die Grundlagen

Ein Anchor wird mit dem Zeichen & vor einem Schluesselnamen definiert, zum Beispiel &common-logging. Dieser Anker markiert den nachfolgenden Block als wiederverwendbar. Ein Alias, eingeleitet mit dem Zeichen *, referenziert diesen Block an einer anderen Stelle im Dokument und fuegt ihn dort exakt so ein, wie er am Anker definiert wurde. Diese zwei Zeichen, & und *, bilden das komplette Vokabular fuer einfache Wiederverwendung in YAML.

Wichtig zu verstehen: Anchors und Aliases sind eine reine YAML-Funktionalitaet und keine Docker Compose spezifische Erweiterung. Das bedeutet, sie funktionieren unabhaengig davon, wo im Dokument sie stehen, solange der Anker vor dem Alias definiert wird. Innerhalb einer compose.yaml lassen sich Anker auf oberster Ebene, in einem services Block oder in speziell dafuer angelegten Extension Fields platzieren, was fuer die Organisation der Datei relevant ist.


# compose.yaml — basic anchor and alias usage
services:
  api:
    image: myapp/api:latest
    logging: &default-logging
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

  worker:
    image: myapp/worker:latest
    logging: *default-logging   # Reuses the exact same logging block

  scheduler:
    image: myapp/scheduler:latest
    logging: *default-logging   # Same logging config, defined only once

In diesem Beispiel wird die Logging-Konfiguration einmal am Service api definiert und ueber den Anker default-logging in worker und scheduler exakt wiederverwendet. Aendert sich der max-size Wert, reicht eine einzige Aenderung an der Ankerstelle, alle drei Services uebernehmen die neue Konfiguration automatisch beim naechsten docker compose up.

3. Merge Keys: Anker erweitern statt komplett ersetzen

Ein reiner Alias fuegt den referenzierten Block unveraendert ein, was in vielen Faellen nicht ausreicht. Haeufig braucht ein Service die meisten Einstellungen eines gemeinsamen Blocks, aber mit ein oder zwei abweichenden Werten. Fuer diesen Fall gibt es den Merge Key, geschrieben als <<: *anker-name. Der Merge Key fuegt alle Schluessel des referenzierten Ankers in das aktuelle Mapping ein und erlaubt es gleichzeitig, einzelne Schluessel direkt danach zu ueberschreiben.

Diese Kombination aus Merge Key und lokaler Ueberschreibung ist der eigentliche Mehrwert von YAML Anchors in Docker Compose, weil reale Services selten zu hundert Prozent identisch konfiguriert sind. Ein typisches Muster: Ein gemeinsamer Basis-Block definiert restart, logging und Netzwerk-Einstellungen, waehrend jeder Service ueber den Merge Key diese Basis uebernimmt und nur sein eigenes image sowie individuelle Umgebungsvariablen ergaenzt.


# compose.yaml — merge key extends a common base
x-common-service: &common-service
  restart: unless-stopped
  networks:
    - backend
  logging:
    driver: json-file
    options:
      max-size: "10m"

services:
  api:
    <<: *common-service
    image: myapp/api:latest
    environment:
      SERVICE_NAME: api

  worker:
    <<: *common-service
    image: myapp/worker:latest
    environment:
      SERVICE_NAME: worker
    restart: on-failure   # Overrides the inherited "unless-stopped"

networks:
  backend:

Im Beispiel erbt der worker Service alle Einstellungen aus common-service, ueberschreibt aber gezielt die restart Policy auf on-failure. Diese Kombination aus zentraler Definition und lokaler Ueberschreibung macht Merge Keys deutlich flexibler als reine Aliase und ist der Grund, warum die meisten produktiven compose.yaml Dateien mit vielen Services auf dieses Muster setzen.

4. Extension Fields: x-Praefix als sauberer Ablageort

Docker Compose validiert das Root-Level einer compose.yaml gegen ein festes Schema, das nur bestimmte Top-Level-Schluessel wie services, networks, volumes und secrets erlaubt. Ein eigener Schluessel wie common-service wuerde ohne Praefix zu einem Validierungsfehler fuehren. Aus diesem Grund unterstuetzt Docker Compose Extension Fields, Top-Level-Schluessel, die mit x- beginnen und von Compose beim Parsen ignoriert werden, aber als Ablageort fuer Anker vollstaendig gueltig sind.

Die Konvention x-Name als Praefix ist keine Docker Compose spezifische Erfindung, sondern folgt derselben Logik wie x- Header in HTTP oder x- Praefixe in anderen Konfigurationsformaten: Ein reservierter Namensraum fuer Erweiterungen, die vom eigentlichen Schema ignoriert werden duerfen. Fuer die Organisation grosser compose.yaml Dateien empfiehlt es sich, alle gemeinsamen Anker am Anfang der Datei unter mehreren x- Schluesseln zu buendeln, etwa x-common-service, x-healthcheck-defaults und x-logging-defaults, statt sie verstreut zwischen den Services zu platzieren.


# compose.yaml — organizing anchors under x- extension fields
x-healthcheck-defaults: &healthcheck-defaults
  interval: 10s
  timeout: 5s
  retries: 5
  start_period: 30s

x-php-base: &php-base
  build:
    context: .
    dockerfile: docker/php/Dockerfile
  volumes:
    - ./src:/var/www/html
  networks:
    - backend

services:
  php-fpm:
    <<: *php-base
    healthcheck:
      <<: *healthcheck-defaults
      test: ["CMD", "php-fpm-healthcheck"]

  php-worker:
    <<: *php-base
    command: ["php", "bin/console", "worker:run"]
    healthcheck:
      <<: *healthcheck-defaults
      test: ["CMD", "pgrep", "-f", "worker:run"]

networks:
  backend:

5. Praxisbeispiel: gemeinsame Logging-Konfiguration

Logging ist eines der haeufigsten Beispiele fuer sinnvolle YAML Anker in der Praxis, weil nahezu jeder Service dieselbe Logging-Strategie braucht. Ohne Anker muesste der json-file Treiber mit max-size und max-file in jedem einzelnen Service manuell wiederholt werden. Mit einem zentralen Anker reicht eine einzige Definition, die per Merge Key oder direktem Alias in allen Services eingebunden wird, und eine spaetere Anpassung der Logrotation betrifft automatisch den gesamten Stack.

Besonders bei produktionsnahen lokalen Entwicklungsumgebungen, in denen mehrere Container parallel Logs schreiben, verhindert eine zentrale Logging-Konfiguration ausserdem, dass einzelne Services versehentlich ohne Groessenbegrenzung laufen und die Docker-Log-Dateien auf dem Host unkontrolliert wachsen. Das ist ein Detail, das bei manueller Kopie leicht uebersehen wird, bei zentraler Ankerdefinition aber automatisch fuer alle Services gilt.

6. Praxisbeispiel: geteilte Umgebungsvariablen und Healthchecks

Ein zweites haeufiges Anwendungsfeld sind Umgebungsvariablen, die von mehreren Services gemeinsam genutzt werden, etwa Datenbank-Zugangsdaten oder ein gemeinsamer API-Endpunkt. Statt diese Variablen in jedem Service erneut aufzulisten, definiert man einen Anker mit den gemeinsamen Werten und ergaenzt in jedem Service nur die individuellen Variablen zusaetzlich ueber eine zweite environment Sektion oder eine env_file Referenz.

Healthchecks profitieren ebenfalls stark von Ankern, weil sich interval, timeout und retries in einem Stack mit mehreren aehnlichen Services selten unterscheiden. Nur der eigentliche test Befehl ist meistens service-spezifisch. Mit einem Merge Key laesst sich der Healthcheck-Rahmen einmal definieren, waehrend jeder Service lediglich seinen eigenen test Befehl ergaenzt, was die Konsistenz der Healthcheck-Parameter ueber den gesamten Stack sicherstellt.


# compose.yaml — shared environment variables via anchor
x-db-credentials: &db-credentials
  DB_HOST: mysql
  DB_PORT: "3306"
  DB_NAME: magento
  DB_USER: magento

services:
  php-fpm:
    image: myapp/php:8.4-fpm
    environment:
      <<: *db-credentials
      DB_PASSWORD: ${DB_PASSWORD}
      APP_ENV: development

  cron:
    image: myapp/php:8.4-cli
    command: ["php", "bin/magento", "cron:run"]
    environment:
      <<: *db-credentials
      DB_PASSWORD: ${DB_PASSWORD}
      APP_ENV: cron

7. Grenzen von Ankern gegenueber include und Override-Dateien

YAML Anchors loesen Wiederholung innerhalb einer einzigen Datei, aber sie funktionieren nicht ueber mehrere Dateien hinweg. Ein Anker, der in compose.yaml definiert wurde, kann nicht in compose.override.yaml referenziert werden, weil YAML jede Datei als eigenstaendiges Dokument parst. Fuer Wiederverwendung ueber Dateigrenzen hinweg bietet Docker Compose stattdessen die include Direktive oder mehrere -f Flags beim docker compose Aufruf, die auf komplett anderer Ebene arbeiten als YAML Anker.

Ein weiterer Punkt: Anker koennen nicht bedingt angewendet werden. Es gibt keine Moeglichkeit, einen Anker nur unter bestimmten Bedingungen einzubinden, etwa abhaengig von einem Compose Profile. Wer bedingte Konfiguration braucht, muss weiterhin mit profiles, separaten Override-Dateien oder Umgebungsvariablen in Kombination mit der Default-Wert-Syntax ${VAR:-default} arbeiten. YAML Anker sind ein Werkzeug gegen textuelle Wiederholung, kein Werkzeug fuer bedingte Logik.

8. Typische Fehler beim Einsatz von Ankern

Der haeufigste Fehler ist, einen Alias zu verwenden, wo eigentlich ein Merge Key noetig gewesen waere. Ein direkter Alias wie logging: *default-logging ersetzt den gesamten Wert, waehrend ein Merge Key mit <<: *anker die Schluessel in das umgebende Mapping einfuegt und lokale Ueberschreibungen erlaubt. Wer versucht, nach einem direkten Alias noch zusaetzliche Schluessel im selben Mapping zu definieren, bekommt einen YAML-Parserfehler, weil ein Alias einen kompletten Wert darstellt und keine weiteren Geschwister-Schluessel im selben Block toleriert.


# WRONG: alias replaces the whole value, cannot add sibling keys after it
services:
  api:
    logging: *default-logging
    # driver: override   <- would be a duplicate mapping key, invalid

# RIGHT: merge key allows extending and overriding
services:
  api:
    logging:
      <<: *default-logging
      driver: syslog   # Overrides only the driver, keeps other options

Ein zweiter haeufiger Fehler betrifft die Reihenfolge: Ein Anker muss im YAML-Dokument vor dem ersten Alias definiert sein, der ihn referenziert. Steht der Anker weiter unten in der Datei als der Alias, meldet der Parser einen Fehler, weil die Referenz zum Zeitpunkt der Verarbeitung noch nicht existiert. Deshalb ist es sinnvoll, alle gemeinsam genutzten Anker unter Extension Fields ganz am Anfang der compose.yaml zu buendeln, noch vor dem services Block.

9. Anchors im Vergleich zu Alternativen

Neben YAML Ankern gibt es weitere Wege, Wiederholung in Docker Compose Konfigurationen zu reduzieren. Jeder Ansatz hat einen anderen Anwendungsbereich, und die Wahl haengt davon ab, ob die Wiederholung innerhalb einer Datei oder ueber mehrere Dateien hinweg auftritt.

Ansatz Gueltigkeitsbereich Bedingte Logik moeglich Einsatzzweck
YAML Anchors/Aliases Innerhalb einer Datei Nein Wiederholte Bloecke wie Logging, Healthchecks
Merge Keys (<<) Innerhalb einer Datei Nein Basis-Bloecke mit lokalen Overrides
include Direktive Ueber mehrere Dateien Teilweise (per Datei) Ganze Service-Definitionen aus anderen Dateien
compose.override.yaml Ueber mehrere Dateien Ja, per Umgebung Dev/Test/CI-spezifische Abweichungen
${VAR:-default} Einzelwerte Ja, per Variable Einzelne Konfigurationswerte parametrisieren

In der Praxis schliessen sich diese Ansaetze nicht aus, sondern ergaenzen sich. YAML Anchors reduzieren Wiederholung innerhalb einer Datei, waehrend Override-Dateien und die include Direktive Wiederholung ueber mehrere Umgebungen hinweg vermeiden. Ein gut strukturierter Stack kombiniert typischerweise Anker fuer gemeinsame Service-Bausteine mit einer compose.override.yaml fuer umgebungsspezifische Anpassungen.

Mironsoft

Docker-Compose-Architektur und Multi-Service-Stacks

Eine compose.yaml, die nicht bei jedem Service kopiert wird?

Wir strukturieren bestehende Docker Compose Stacks mit Ankern, Merge Keys und Extension Fields, reduzieren Wiederholung und machen Aenderungen an einer Stelle statt an zehn.

Compose-Refactoring

Bestehende Stacks auf Anker und Merge Keys umstellen, ohne Verhalten zu aendern

Extension Fields

Gemeinsame Basis-Bloecke fuer Logging, Healthchecks und Netzwerke einfuehren

Magento-Stacks

PHP-FPM, Cron, Worker und Node-Build-Services konsistent konfigurieren

10. Zusammenfassung

YAML Anchors, Aliases und Merge Keys loesen ein Problem, das jede wachsende compose.yaml frueher oder spaeter trifft: identische Bloecke fuer Logging, Healthchecks und Umgebungsvariablen, die in jedem Service manuell wiederholt werden. Mit dem & Zeichen wird ein Block als Anker markiert, mit * wird er als Alias referenziert, und mit dem Merge Key << laesst sich ein Anker in ein Mapping einfuegen und gleichzeitig lokal ueberschreiben. Extension Fields mit x-Praefix bieten dafuer einen sauberen, von Compose ignorierten Ablageort am Dateianfang.

Der groesste Gewinn liegt in der Wartbarkeit: Eine Aenderung an einer zentralen Ankerstelle wirkt sich automatisch auf alle referenzierenden Services aus, statt manuell an mehreren Stellen nachgezogen werden zu muessen. Fuer Wiederholung ueber mehrere Dateien hinweg, etwa zwischen compose.yaml und compose.override.yaml, sind Anker nicht geeignet, hier uebernehmen die include Direktive oder separate Override-Dateien die entsprechende Rolle.

YAML Anchors und Aliases in Docker Compose — Das Wichtigste auf einen Blick

Anchor (&)

Markiert einen Block als wiederverwendbar, direkt an der Definitionsstelle im Dokument.

Alias (*)

Fuegt den referenzierten Block exakt und unveraendert an einer anderen Stelle ein.

Merge Key (<<)

Fuegt die Schluessel eines Ankers in ein Mapping ein und erlaubt lokale Ueberschreibungen.

Extension Fields (x-)

Von Compose ignorierte Top-Level-Schluessel, idealer Ablageort fuer gemeinsame Anker.

11. FAQ: YAML Anchors und Aliases in Docker Compose

1Was sind YAML Anchors und Aliases?
Eine native YAML-Funktion fuer einmalige Definition und Wiederverwendung von Bloecken per & und *.
2Alias vs. Merge Key?
Alias ersetzt komplett, Merge Key fuegt Schluessel ein und erlaubt lokale Ueberschreibung.
3Wo gehoeren gemeinsame Anker hin?
Unter x-Extension-Fields am Dateianfang, vor dem services Block.
4Was sind Extension Fields?
Top-Level-Schluessel mit x-Praefix, von Compose ignoriert, idealer Anker-Ablageort.
5Funktionieren Anker ueber mehrere Dateien?
Nein, nur innerhalb derselben Datei. Fuer mehrere Dateien: include Direktive oder Override-Dateien.
6Bedingte Konfiguration mit Ankern?
Nicht moeglich, dafuer Profiles, Override-Dateien oder ${VAR:-default} verwenden.
7Fehler bei zusaetzlichen Schluesseln nach Alias?
Alias ersetzt komplett, keine Geschwister-Schluessel erlaubt, hier braucht es einen Merge Key.
8Muss der Anker vor dem Alias stehen?
Ja, YAML verarbeitet von oben nach unten, der Anker muss vorher definiert sein.
9Eignen sich Anker fuer Healthchecks?
Sehr gut, gemeinsame Parameter zentral definieren, nur test pro Service ergaenzen.
10Verlangsamen viele Anker das Parsing?
Nicht messbar, YAML-Parser sind dafuer optimiert.