E-NO
DevOps 9 min de lecture

Docker Compose : concepts avancés, patterns et écueils — guide pratique d’implémentation

calendar_today Publié : 2026-07-14
update Dernière mise à jour : 2026-07-14
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Docker Compose : concepts avancés, patterns et écueils — guide pratique d’implémentation ».

Intro

Le Docker Compose « avancé » ne consiste pas à lancer plus de conteneurs, mais à maîtriser la façon dont les services sont construits, démarrés, découverts, configurés, sécurisés et observés comme une unité unique et prévisible. Dans ce guide, vous allez :

  • Comprendre comment Compose groupe les ressources et résout la configuration pour prédire le comportement.
  • Appliquer les profils, les healthchecks avec dépendances conditionnelles, les secrets et configs, les ancres, et les overrides multi‑fichiers.
  • Durcir les conteneurs (système de fichiers en lecture seule, no‑new‑privileges, ulimits) et éviter les erreurs courantes.
  • Lancer un pilote local ciblé qui prouve la valeur sans risquer la production.

Vue d’ensemble du workflow

Suivez ce flux de déploiement sûr :

  1. Concevoir le graphe de services
  • Définissez les services, leurs frontières de données et les ports publiés. Utilisez des volumes nommés pour l’état.
  • Conservez le réseau de projet par défaut pour la découverte DNS ; évitez les bridges personnalisés sauf nécessité.
  1. Construire
  • Utilisez un contexte de build réduit, des cibles multi‑étapes et des build args. Activez BuildKit. Favorisez le cache de couches et un .dockerignore robuste.
  1. Exécuter
  • Démarrez avec un nom de projet explicite, activez des outils optionnels via des profils et ajoutez des healthchecks. Utilisez depends_on avec des conditions pour piloter la « prêtitude », pas seulement l’ordre de démarrage.
  1. Observer
  • Streamez les logs, inspectez l’état de santé et testez les noms DNS sur le réseau du projet.
  1. Durcir
  • Ajoutez des systèmes de fichiers en lecture seule quand c’est possible, définissez des ulimits et montez les secrets comme fichiers. Évitez deploy.* sauf si vous utilisez Swarm.

Les mécanismes internes de Compose qui comptent

  • Nom de projet
  • Compose groupe tout par un nom de projet. Définissez‑le avec le champ de niveau supérieur name: ou l’option -p. Les réseaux et volumes reçoivent ce préfixe, isolant les projets sur le même hôte.
  • Réseau par défaut
  • Compose crée un réseau bridge défini par l’utilisateur pour chaque projet. Chaque nom de service est un hostname DNS sur ce réseau (par exemple, db résout vers le conteneur Postgres). Vous n’avez pas besoin de links.
  • Fusion de fichiers
  • Plusieurs fichiers passés avec -f fusionnent de haut en bas. Les fichiers ultérieurs surchargent ou étendent les précédents. Conservez un fichier de base stable et superposez les changements spécifiques à l’environnement.
  • Résolution des variables d’environnement
  • Compose prend en charge ${VAR} et ${VAR:-default} dans le YAML. Il lit un .env dans le répertoire du projet et votre environnement shell ; les valeurs du shell priment sur .env. env_file sous un service injecte des variables dans le conteneur uniquement et n’affecte pas la substitution au niveau Compose.
  • Ordonnancement vs « prêtitude »
  • depends_on sans conditions n’ordonne que le démarrage. Pour la prêtitude, définissez un healthcheck et utilisez depends_on: condition: service_healthy.
  • État de santé
  • Les services avec healthchecks rapportent starting, healthy ou unhealthy. Interrogez avec docker compose ps et docker compose logs.
  • Clés spécifiques à Swarm
  • Les clés sous deploy.* sont destinées au mode Swarm. Docker Compose (hôte unique) en ignore la plupart. Utilisez les options au niveau service (environment, volumes, ulimits, read_only, mem_limit, cpus, etc.) hors Swarm.
  • Champ de version
  • Le Compose moderne ne requiert pas version:. Omettez‑le et fiez‑vous à la spécification Compose prise en charge par votre CLI.

Question rapide 1 sur 2

Quel est l'objectif principal des fichiers Docker Compose tel que décrit sur Docker Hub ?

Le passage indique que « Compose est un outil pour définir et exécuter des applications Docker multi-conteneurs » et que Docker Hub héberge des fichiers Compose pour faciliter l'orchestration multi-conteneurs.

Concepts avancés avec un exemple proche de la production

Un fichier de base concis montrant des patterns concrets : profils, dépendances conditionnées par l’état de santé, secrets/configs, ancres et paramètres sûrs par défaut.

# compose.yml
name: myapp

# Champs d’extension et ancres pour la réutilisation
x-service-defaults: &service_defaults
  restart: unless-stopped
  networks:
    - appnet
  env_file:
    - ./.env
  init: true
  logging:
    driver: json-file
    options:
      max-size: "10m"
      max-file: "3"
  mem_limit: 512m
  cpus: "0.50"

x-healthchecks:
  postgres: &pg_health
    test: ["CMD-SHELL", "pg_isready -U $POSTGRES_USER -d $POSTGRES_DB"]
    interval: 3s
    timeout: 3s
    retries: 10
    start_period: 10s
  redis: &redis_health
    test: ["CMD", "redis-cli", "ping"]
    interval: 3s
    timeout: 3s
    retries: 10
    start_period: 5s
  web: &web_health
    test: ["CMD", "wget", "-qO-", "http://localhost/healthz"]
    interval: 5s
    timeout: 3s
    retries: 10
    start_period: 5s

services:
  db:
    <<: *service_defaults
    image: postgres:16
    environment:
      POSTGRES_DB: app
      POSTGRES_USER: app
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck: *pg_health
    secrets:
      - db_password
    ulimits:
      nofile: 65535

  cache:
    <<: *service_defaults
    image: redis:7
    command: ["redis-server", "--appendonly", "yes"]
    volumes:
      - redisdata:/data
    healthcheck: *redis_health

  web:
    <<: *service_defaults
    build:
      context: ./web
      dockerfile: Dockerfile
      target: runtime
      args:
        APP_ENV: ${APP_ENV:-dev}
      ssh:
        - default
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_healthy
    ports:
      - "127.0.0.1:8080:80"  # lier en local pour éviter une exposition sur le LAN
    healthcheck: *web_health
    read_only: true
    tmpfs:
      - /tmp
    security_opt:
      - no-new-privileges:true
    configs:
      - source: nginx_conf
        target: /etc/nginx/conf.d/app.conf

  adminer:
    <<: *service_defaults
    image: adminer:4
    profiles: ["tools"]
    ports:
      - "127.0.0.1:8081:8080"

configs:
  nginx_conf:
    file: ./deploy/nginx/app.conf

secrets:
  db_password:
    file: ./secrets/db_password.txt

networks:
  appnet: {}

volumes:
  pgdata: {}
  redisdata: {}

Points clés :

  • name: myapp définit un préfixe de projet stable pour réseaux et volumes.
  • Les ancres réduisent les duplications et préviennent la dérive de configuration.
  • Les healthchecks avec depends_on: condition: service_healthy imposent que web attende la prêtitude de Postgres et Redis.
  • Les secrets et configs montent des fichiers dans les conteneurs. Protégez leurs sources dans votre répertoire de travail.
  • read_only et no-new-privileges durcissent le conteneur web. Un tmpfs pour /tmp évite les écritures dans l’image.
  • Liezen les ports à 127.0.0.1 en dev local pour éviter toute exposition involontaire.

Overrides locaux pour itération rapide

Utilisez un override pour bind‑monter le code source et activer des flags de debug sans toucher au fichier de base. compose.override.yml est auto‑chargé par docker compose.

# compose.override.yml
services:
  web:
    volumes:
      - ./web/src:/var/www/src:rw,cached
    environment:
      DEBUG: "1"

Pour des superpositions explicites et propres à l’environnement, créez un fichier dédié et passez‑le avec -f.

# compose.prod.yml
services:
  web:
    environment:
      APP_ENV: prod
    ports:
      - "80:80"  # publier sur le port standard en prod
  adminer:
    profiles: ["never"]  # s’assurer que les outils restent inactifs en prod

Exécutez avec :

# Base + overlay prod explicite
docker compose -f compose.yml -f compose.prod.yml up -d

Variables d’environnement et .env

Créez un .env dans le répertoire du projet pour la substitution au niveau Compose et les valeurs communes :

# .env
APP_ENV=dev
POSTGRES_PASSWORD=unused_when_using_secret
# Le fichier secrets/db_password.txt reste requis pour le secret

Notes :

  • Les variables du shell priment sur .env pour la substitution : APP_ENV=staging docker compose up utilisera staging.
  • env_file injecte des variables uniquement dans le conteneur ciblé et n’influence pas l’interpolation de Compose.
  • Préférez les secrets pour les valeurs sensibles ; évitez de les committer au VCS.

Builds multi‑étapes avec BuildKit et SSH

Utilisez des builds multi‑étapes pour des images runtime compactes. Avec BuildKit, vous pouvez transférer votre agent SSH en toute sécurité pour récupérer des dépendances privées.

Exemple : une image compacte pour un service Go.

# api/Dockerfile
FROM golang:1.22 AS build
WORKDIR /src
# optionnel : utiliser le SSH de BuildKit pour récupérer des deps privées
# RUN --mount=type=ssh go env -w GOPRIVATE=github.com/yourorg/*
COPY go.mod go.sum ./
RUN --mount=type=cache,target=/go/pkg/mod go mod download
COPY . .
RUN CGO_ENABLED=0 go build -ldflags='-s -w' -o /out/api ./cmd/api

FROM gcr.io/distroless/base-debian12 AS runtime
COPY --from=build /out/api /usr/local/bin/api
USER 65532:65532
EXPOSE 8080
ENTRYPOINT ["/usr/local/bin/api"]

Activez BuildKit et construisez avec transfert SSH :

export DOCKER_BUILDKIT=1
export COMPOSE_DOCKER_CLI_BUILD=1
ssh-add -l >/dev/null 2>&1 || ssh-add
# Si le service api est dans votre fichier Compose, vous pouvez le construire ainsi :
docker compose build --ssh default

Question rapide 2 sur 2

Lequel des éléments suivants est un avantage de Docker Compose en matière de cohérence des environnements ?

Le passage cite « Cohérence des environnements : garantir un comportement cohérent de l'application dans les environnements de développement, de staging et de production » comme un avantage.

Plan de pilote local

Démarrez par un pilote étroit et mesurable qui exerce les fonctionnalités les plus utiles sans complexifier.

Objectifs du pilote :

  • Prouver que le démarrage conditionné par l’état de santé fonctionne (web attend db et cache).
  • Valider le montage des secrets et des configs.
  • Confirmer le périmètre du projet et la découverte de service via le réseau de l’appli.

Préparation :

# Créer les répertoires et fichiers
mkdir -p deploy/nginx secrets web/src
printf 'server {\n  listen 80;\n  location /healthz { return 200 "ok"; }\n  location / { return 200 "hello"; }\n}\n' > deploy/nginx/app.conf
umask 077 && printf 'supersecretpassword\n' > secrets/db_password.txt

# Optionnel : ajouter .env avec APP_ENV=dev

Lancer le pilote :

# Démarrer la pile de base
docker compose up -d --build
# Ou inclure le profil d’outils optionnel
docker compose --profile tools up -d --build

Validation :

# Vérifier l’état des services et la santé
docker compose ps

# Attendre que tous les services soient healthy (versions récentes)
docker compose up --wait

# Atteindre l’endpoint web
curl -sS http://localhost:8080/healthz

# Confirmer la découverte DNS de web vers db
docker compose exec web getent hosts db

# Vérifier que les secrets sont montés dans db
docker compose exec db ls -l /run/secrets

Nettoyage propre une fois terminé :

docker compose down --volumes

Erreurs de configuration courantes et correctifs rapides

  • Utiliser le tag latest partout
  • Correctif : épinglez les images (par ex. postgres:16, redis:7) pour éviter les mises à jour surprises.
  • Publier les ports au monde par défaut
  • Correctif : liez à localhost en dev (127.0.0.1:8080:80). Ne publiez les ports publics qu’en production via des overlays.
  • Penser que depends_on attend la prêtitude
  • Correctif : ajoutez un healthcheck et depends_on: condition: service_healthy. Assurez‑vous que l’endpoint de santé est léger et fiable.
  • Confondre .env avec env_file
  • Correctif : utilisez .env pour l’interpolation Compose et env_file par service pour l’environnement du conteneur. Rappelez‑vous que l’environnement du shell prime sur .env.
  • Monter les données de base de données avec des bind mounts
  • Correctif : utilisez des volumes nommés pour les bases (pgdata, redisdata). C’est plus portable et plus sûr.
  • Ajouter des options deploy.* dans un Compose hors Swarm
  • Correctif : retirez deploy.*. En local, utilisez mem_limit, cpus, ulimits, read_only, etc.
  • Forcer container_name
  • Correctif : évitez container_name. Cela casse le scaling et l’unicité des noms. Laissez Compose générer des noms avec le préfixe de projet.
  • Healthchecks instables
  • Correctif : ajustez start_period, interval et retries. Préférez CMD-SHELL quand vous avez besoin du shell ; sinon, utilisez des tableaux CMD.
  • Builds volumineux et lents
  • Correctif : réduisez le contexte de build, utilisez .dockerignore, des builds multi‑étapes et les caches BuildKit.

Conseils pratiques et paramètres sûrs par défaut

  • Utilisez des volumes nommés pour les bases de données ; évitez de bind‑monter leurs répertoires de données.
  • Conservez le réseau de projet par défaut et fiez‑vous aux noms de service pour le DNS. Ne publiez que les ports réellement nécessaires.
  • Préférez les healthchecks avec depends_on conditionnel aux scripts d’attente ad hoc.
  • Utilisez des profils pour laisser les outils optionnels inactifs par défaut.
  • Durcissez avec read_only, no-new-privileges, ulimits et des utilisateurs non‑root quand c’est possible.
  • Traitez les secrets locaux comme sensibles : restreignez les permissions de ./secrets et ne les commitez jamais.
  • Gardez vos fichiers Compose concis et factorisez les overrides par environnement.

Conclusion

Vous disposez désormais d’un modèle pratique et à jour sur la façon dont Docker Compose groupe les services, câble le réseau et la découverte, résout la configuration et impose la prêtitude. Commencez par le pilote local pour valider le démarrage piloté par l’état de santé, les secrets et les configs. Ensuite, superposez des fichiers spécifiques à l’environnement, durcissez les conteneurs avec des systèmes de fichiers en lecture seule et no-new-privileges, épinglez les images et maintenez les outils optionnels derrière des profils. Cette approche progressive et disciplinée réduit les risques tout en libérant Compose pour des opérations quotidiennes rapides et fiables.

Recherches connexes

Score de qualité de l’article

Utilité pour le lecteur 100%
  • check_circle Guide prêt à lire
  • check_circle Exemples pratiques inclus
  • check_circle URL d’article optimisée pour le SEO