Docker pour les devs - 10 - Docker Compose avance

Profiles, override files, extends, ancres YAML, docker compose watch et include pour un Compose flexible et maintenable.

  1. 01 Docker pour les devs - 00 - Pourquoi Docker change tout
  2. 02 Docker pour les devs - 01 - Containers vs VMs
  3. 03 Docker pour les devs - 02 - L'architecture de Docker
  4. 04 Docker pour les devs - 03 - Docker Desktop, Engine et alternatives
  5. 05 Docker pour les devs - 04 - Écrire un Dockerfile
  6. 06 Docker pour les devs - 05 - Layers et cache
  7. 07 Docker pour les devs - 06 - Le .dockerignore
  8. 08 Docker pour les devs - 07 - Multi-stage builds
  9. 09 Docker pour les devs - 08 - Choisir son image de base
  10. 10 Docker pour les devs - 09 - Docker Compose, les bases
  11. 11 Docker pour les devs - 10 - Docker Compose avance
  12. 12 Docker pour les devs - 11 - Networking Docker, les bases
  13. 13 Docker pour les devs - 12 - Networking Docker avance
  14. 14 Docker pour les devs - 13 - Volumes et persistance
  15. 15 Docker pour les devs - 14 - Variables d'environnement et secrets
  16. 16 Docker pour les devs - 15 - Permissions et utilisateurs
  17. 17 Docker pour les devs - 16 - Docker et monorepo
  18. 18 Docker pour les devs - 17 - Dev vs Prod
  19. 19 Docker pour les devs - 18 - ENTRYPOINT, CMD et scripts d'initialisation
  20. 20 Docker pour les devs - 19 - Debugger ses conteneurs
  21. 21 Docker pour les devs - 20 - Bases de donnees dans Docker
  22. 22 Docker pour les devs - 21 - Sauvegardes et restauration
  23. 23 Docker pour les devs - 22 - Conteneuriser un frontend
  24. 24 Docker pour les devs - 23 - Sécurité des conteneurs
  25. 25 Docker pour les devs - 24 - Optimisation des images
  26. 26 Docker pour les devs - 25 - Builds multi-platform
  27. 27 Docker pour les devs - 26 - Limiter les ressources de tes conteneurs
  28. 28 Docker pour les devs - 27 - Gerer les logs comme un adulte
  29. 29 Docker pour les devs - 28 - Healthchecks et restart policies
  30. 30 Docker pour les devs - 29 - Nettoyer Docker avant qu'il mange ton disque
  31. 31 Docker pour les devs - 30 - Registries et stratégie de tags
  32. 32 Docker pour les devs - 31 - Docker en CI/CD
  33. 33 Docker pour les devs - 32 - Au-dela de Compose
  34. 34 Docker pour les devs - 33 - Glossaire Docker de A a Z

10 - Docker Compose avance

Ce que tu vas apprendre

  • Les profiles pour activer des services uniquement en dev
  • Les fichiers override et la fusion de configurations
  • La directive extends pour factoriser
  • Les ancres YAML pour éviter la répétition
  • Docker Compose Watch pour le rechargement automatique
  • La directive include pour les gros projets

Prerequisites


Une fois que tu maitrises le compose.yaml de base, tu te retrouves vite avec un fichier de 200 lignes ou tu repetes les memes blocs partout. Docker Compose a des mecanismes pour gerer ca proprement. Je les ai tous utilises sur paltemps.fr, et certains m'ont fait gagner des heures.

Profiles : des services a la carte

Tu as un service Mailhog pour intercepter les mails en dev. Pas question de le lancer en production. Les profiles resolvent ca :

yamlservices:
  app:
    build: .
    ports:
      - "3000:3000"

  mailhog:
    image: mailhog/mailhog
    ports:
      - "8025:8025"
    profiles:
      - dev

  adminer:
    image: adminer
    ports:
      - "8080:8080"
    profiles:
      - dev
      - debug

Par défaut, docker compose up ne lance que les services sans profil. Pour activer un profil :

bashdocker compose --profile dev up -d

Tu peux aussi définir la variable d'environnement COMPOSE_PROFILES=dev dans ton .env. Plusieurs profils se separent par une virgule.

Override files : la fusion automatique

Compose fusionne automatiquement compose.yaml et compose.override.yaml quand les deux existent. C'est le mecanisme que j'utilise le plus.

Le fichier principal, compose.yaml :

yamlservices:
  app:
    build: .
    ports:
      - "3000:3000"
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_PASSWORD: secret

Le fichier compose.override.yaml (charge automatiquement) :

yamlservices:
  app:
    volumes:
      - .:/app
    command: node --watch src/index.js
    environment:
      DEBUG: "true"

Quand tu lances docker compose up, les deux fichiers sont fusionnes. Le service app aura les ports du premier fichier ET les volumes et la commande du second.

Pour utiliser un fichier spécifique a la place :

bashdocker compose -f compose.yaml -f compose.prod.yaml up -d

On exploite ce pattern en détail dans l'article dev vs prod.

extends : factoriser les services

Quand plusieurs services partagent la meme configuration de base, extends évité la duplication :

yamlservices:
  base-node:
    build: .
    environment:
      NODE_ENV: production
    deploy:
      resources:
        limits:
          memory: 512M

  api:
    extends:
      service: base-node
    ports:
      - "3000:3000"
    command: node dist/api.js

  worker:
    extends:
      service: base-node
    command: node dist/worker.js

api et worker heritent de base-node et ajoutent leurs spécificités. Le service base-node ne sera pas démarré lui-meme (sauf si tu lui ajoutes un command).

Tu peux aussi extends un service depuis un autre fichier :

yamlservices:
  api:
    extends:
      file: common.yaml
      service: base-node

Ancres YAML : la magie du &

YAML supporte nativement les ancres et les alias. C'est du YAML pur, pas une fonctionnalité Docker. Mais c'est dans les fichiers Compose que tu les verras le plus.

yamlx-common-env: &common-env
  TZ: Europe/Paris
  NODE_ENV: production

x-healthcheck: &default-healthcheck
  interval: 10s
  timeout: 5s
  retries: 3

services:
  api:
    build: .
    environment:
      <<: *common-env
      PORT: "3000"
    healthcheck:
      <<: *default-healthcheck
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]

  worker:
    build: .
    environment:
      <<: *common-env
      QUEUE: default
    healthcheck:
      <<: *default-healthcheck
      test: ["CMD", "curl", "-f", "http://localhost:3001/health"]

Le &common-env créé une ancre. Le *common-env la référencé. Le <<: fusionne le contenu dans le mapping courant. Les clés apres <<: ecrasent celles de l'ancre.

Les blocs x- en racine sont des extensions personnalisees. Compose les ignore, mais ils sont parfaits pour stocker des ancres.

Docker Compose Watch

Depuis Compose v2.22, docker compose watch surveille tes fichiers et reagit aux changements sans redemarrer manuellement :

yamlservices:
  app:
    build: .
    develop:
      watch:
        - action: sync
          path: ./src
          target: /app/src
        - action: rebuild
          path: package.json

Trois actions possibles :

  • sync : copie les fichiers modifies dans le conteneur (comme un bind mount intelligent)
  • rebuild : reconstruit l'image et relance le conteneur
  • sync+restart : copie les fichiers et relance le conteneur
bashdocker compose watch

L'avantage sur un bind mount classique ? Watch gere les différences de système de fichiers entre host et conteneur, et tu peux choisir l'action par type de fichier.

La directive include

Pour les gros projets avec plusieurs fichiers Compose, include permet de les combiner :

yamlinclude:
  - path: ./infra/compose.yaml
  - path: ./monitoring/compose.yaml

services:
  app:
    build: .
    depends_on:
      - db  # defini dans infra/compose.yaml

Chaque fichier inclus garde son propre contexte de build. C'est plus propre que la fusion manuelle avec -f.

Compose merge : combiner des fichiers

La commande docker compose config montre le résultat de la fusion de tous tes fichiers :

bashdocker compose -f compose.yaml -f compose.override.yaml config

Ca affiche le YAML final, apres fusion. C'est indispensable pour debugger quand tu ne comprends pas pourquoi un service a un mauvais port ou une mauvaise variable.

Résumé

  • Les profiles activent des services a la demande (--profile dev)
  • Le fichier override est fusionne automatiquement, parfait pour les configs dev
  • extends factorise les services qui partagent une base commune
  • Les ancres YAML (&, *, <<:) eliminent la répétition dans le fichier
  • watch synchronise les fichiers et relance les builds automatiquement
  • include decoupe un gros Compose en plusieurs fichiers independants

Navigation : Precedent : 09 - Compose bases | Suivant : 11 - Networking bases


Sources

Réservez un audit gratuit de 30 minutes. Je vous montre concrètement ce qu'on peut automatiser.