infra / docker-compose
YAML avancé : ancres, alias et fusion (merge keys)
Explication
Ce que vous allez apprendre
- Déclarer un bloc de configuration réutilisable avec une ancre YAML (
&nom) - Réutiliser ce bloc ailleurs dans le fichier avec un alias (
*nom) - Fusionner un bloc ancré dans un service tout en y ajoutant des clés propres (
<<:) - Utiliser la convention
x-pour ranger ces blocs sans qu'ils soient interprétés comme des services - Repérer que ce mécanisme appartient au langage YAML lui-même, pas seulement à Compose
Dans quel contexte ?
Sur le projet boutique-api, les services api et worker partagent exactement le même healthcheck et la même politique de logs, copiés-collés service par service. Le jour où l'équipe doit changer l'intervalle du healthcheck de 10 à 15 secondes, elle oublie de le faire sur worker, qui continue de tourner avec l'ancienne valeur pendant plusieurs semaines sans que personne ne s'en aperçoive. Les ancres YAML éliminent ce risque en centralisant la définition.
Le problème : du copier-coller dans le YAML
D'abord, imagine plusieurs services qui partagent presque le même healthcheck ou la même politique de logs. Sans solution particulière, on finit par copier-coller cette configuration service après service dans le fichier.
Le risque de cette duplication
Le jour où il faut changer une seule valeur, il faut la changer partout où elle a été copiée. Il est alors facile d'en oublier une, exactement comme pour la duplication de code dans un vrai programme.
Une précision avant de continuer
Il faut savoir que ce mécanisme n'appartient pas à Compose : c'est une fonctionnalité du langage YAML lui-même, utilisable dans n'importe quel fichier YAML, pas seulement docker-compose.yml.
Première brique : l'ancre
Une ancre, écrite &nom, marque un bloc de configuration comme réutilisable. C'est un peu comme donner un nom à une variable, mais pour un bloc entier de configuration.
Deuxième brique : l'alias
Une fois une ancre définie, un alias, écrit *nom, permet de réutiliser ce bloc ailleurs dans le fichier, tel quel, sans jamais le retaper.
Aller plus loin : la fusion avec <<:
Il reste un besoin : réutiliser un bloc ET lui ajouter des clés supplémentaires. C'est le rôle de la clé de fusion <<:, qui injecte le contenu d'un bloc ancré dans un autre mapping, avant d'ajouter ou de surcharger certaines valeurs localement.
Où ranger ces blocs réutilisables
Maintenant que tu sais créer des ancres, une question d'organisation se pose : où les placer sans polluer la liste des vrais services ? Compose répond en ignorant volontairement toute clé de premier niveau commençant par x-, une convention prévue justement pour stocker ces blocs.
| Symbole | Nom | Rôle |
|---|---|---|
&nom | Ancre | Marque un bloc comme réutilisable |
*nom | Alias | Référence le bloc ancré tel quel |
<<: | Clé de fusion | Injecte le bloc ancré, puis autorise des ajouts locaux |
x-nom | Extension | Clé racine ignorée par Compose, faite pour stocker des ancres |
Les pièges à connaître
Une clé définie localement après un <<: écrase la valeur héritée de l'ancre, ce qui est utile pour personnaliser un bloc partagé mais peut surprendre si on ne s'y attend pas. Attention aussi à ne pas abuser des ancres au point de rendre le fichier illisible : garde le réflexe de toujours vérifier le résultat final avec docker compose config.
Bonne pratique
Regroupe toutes tes ancres réutilisables sous des clés x- en haut du fichier (x-healthcheck-default, x-logging-default) plutôt que de les disperser. N'importe quel nouveau membre de l'équipe comprend alors immédiatement où chercher la configuration partagée.
La leçon suivante change complètement de sujet : au lieu d'alléger le fichier YAML, elle installe un reverse proxy capable de router automatiquement le trafic vers tes services, sans jamais éditer sa configuration à la main.
Commandes & code
YAML avancé : ancres, alias et fusion (merge keys)
Les ancres YAML évitent de dupliquer une configuration identique entre plusieurs services d'un même fichier Compose.
# Ancre (&nom) définit un bloc réutilisable, alias (*nom) le référence tel quel
x-healthcheck-default: &default-healthcheck
interval: 10s
timeout: 3s
retries: 5
start_period: 15s
x-logging-default: &default-logging
driver: json-file
options:
max-size: "10m"
max-file: "3"
services:
api:
build: ./api
healthcheck:
<<: *default-healthcheck # fusionne le bloc ancré ici
test: ["CMD", "wget", "-qO-", "http://localhost:3000/health"]
logging: *default-logging
worker:
build: ./worker
healthcheck:
<<: *default-healthcheck
test: ["CMD", "node", "healthcheck.js"]
logging: *default-logging# "x-" est un préfixe réservé par Compose : ces clés sont ignorées à l'exécution,
# elles servent UNIQUEMENT de zone de définition pour ancres/alias réutilisables.
x-common-env: &common-env
TZ: Europe/Paris
LOG_FORMAT: json
services:
api:
build: ./api
environment:
<<: *common-env
SERVICE_NAME: api # clé supplémentaire propre à ce service
worker:
build: ./worker
environment:
<<: *common-env
SERVICE_NAME: worker# Fusion de PLUSIEURS ancres avec la syntaxe de liste de merge keys
x-base: &base
restart: unless-stopped
x-resources: &resources
deploy:
resources:
limits:
memory: 256M
services:
api:
build: ./api
<<: [*base, *resources] # fusionne les deux blocs au niveau racine du service# Toujours valider le résultat final : les ancres/alias sont résolus AVANT interprétation
docker compose configRésumé
&nomdéclare une ancre,*nomla référence,<<:fusionne un mapping ancré dans un autre.- Le préfixe
x-marque des clés d'extension ignorées par Compose, idéales pour stocker des ancres. - Une clé locale après
<<:écrase la valeur héritée de l'ancre (comme un override). docker compose configaffiche toujours le YAML une fois les ancres/alias résolus.
Exercices pratiques
Mission : deux services, un seul healthcheck qui diverge
Objectif : Prédire le résultat d'une fusion d'ancre YAML avec surcharge locale, puis factoriser une configuration dupliquée.
Contexte
Sur boutique-api, une ancre &default-healthcheck définit interval: 10s. Le service worker utilise <<: *default-healthcheck puis redéfinit localement interval: 30s. Par ailleurs, api et worker dupliquent exactement la même configuration logging, copiée-collée service par service.
Prédis le résultat de la fusion, puis factorise la configuration dupliquée.