Vue d’ensemble

Docker Compose définit les applications multi-conteneurs dans un seul fichier YAML. Cet aide-mémoire couvre la structure de compose.yaml, chaque clé de service, les options d’environnement et de configuration, la mise en réseau et les volumes, l’intégralité de la CLI, les fichiers override, et les profiles. Tous les exemples ciblent Docker Compose v2 (le plugin docker compose) et la spécification Compose ; la clé version: héritée est obsolète et ignorée.

Structure compose.yaml

La structure de base d’un fichier Compose :

services:      # Définir les services conteneurisés
volumes:       # Définir les volumes nommés
networks:      # Définir les réseaux personnalisés
configs:       # Définir les configs (pour swarm, optionnel)
secrets:       # Définir les secrets (pour swarm, optionnel)

Services : clés de base

Clé Objectif Exemple
image: <name>:<tag> Utiliser une image pré-construite image: nginx:1.27
build: <path> Construire une image à partir d’un Dockerfile dans le chemin donné build: . ou build: ./services/web
build: { context: <path>, dockerfile: <file> } Construire avec contexte et chemin Dockerfile explicites build: { context: ., dockerfile: Dockerfile.prod }
build: { context: <path>, args: { VAR: value } } Passer des arguments de build build: { context: ., args: { NODE_ENV: production } }
container_name: <name> Définir le nom du conteneur (non recommandé pour la mise à l’échelle) container_name: my_web_app
restart: <policy> Politique de redémarrage : no, always, on-failure, unless-stopped restart: unless-stopped
restart: on-failure:<max-retries> Redémarrer en cas d’échec jusqu’à N fois restart: on-failure:5

Mise en réseau et ports

Clé Objectif Exemple
ports: [<host>:<container>] Mapper le port du conteneur vers l’hôte ports: ["8080:80"]
ports: [<host-ip>:<host>:<container>] Mapper vers une IP d’hôte spécifique ports: ["127.0.0.1:8080:80"]
ports: [<container>] Exposer sans mapper vers l’hôte ports: ["8080"]
expose: [<port>] Exposer le port pour la communication interne (pas de mapping hôte) expose: ["8080"]
networks: [<network>] Attacher le service aux réseaux personnalisés networks: [frontend, backend]
networks: <network>: { ipv4_address: <ip> } Assigner une IP statique networks: { backend: { ipv4_address: 172.20.0.2 } }
hostname: <name> Définir le nom d’hôte du conteneur hostname: db-server
links: [<service>] Lier à un autre service (hérité, utiliser les réseaux à la place) links: [db]
dns: [<ip>] Définir les serveurs DNS dns: [8.8.8.8, 8.8.4.4]
dns_search: [<domain>] Définir les domaines de recherche DNS dns_search: [example.com]

Environnement et configuration

Clé Objectif Exemple
environment: { VAR: value } Définir les variables d’environnement en ligne environment: { DEBUG: "true", LOG_LEVEL: info }
environment: [VAR=value] Définir les variables d’environnement en tant que liste environment: [DEBUG=true, LOG_LEVEL=info]
env_file: <file> Charger les variables d’environnement à partir d’un fichier env_file: .env
env_file: [<file1>, <file2>] Charger à partir de plusieurs fichiers (les fichiers ultérieurs remplacent les antérieurs) env_file: [.env, .env.local]
working_dir: <path> Définir le répertoire de travail à l’intérieur du conteneur working_dir: /app
command: <command> Remplacer la CMD du Dockerfile command: python -u app.py
command: [<cmd>, <arg1>, <arg2>] Commande en tant que liste (forme exec, préférée) command: [python, -u, app.py]
entrypoint: <cmd> Remplacer ENTRYPOINT du Dockerfile entrypoint: /bin/bash
entrypoint: [<cmd>, <arg>] ENTRYPOINT en tant que liste (forme exec, préférée) entrypoint: [python, -u]
stdin_open: true Garder stdin ouvert même si non attaché stdin_open: true
tty: true Allouer un pseudo-terminal tty: true

Stockage : volumes et bind mounts

Clé Objectif Exemple
volumes: [<host>:<container>] Bind mount un répertoire hôte volumes: [./data:/app/data]
volumes: [<name>:<container>] Monter un volume nommé volumes: [my_data:/app/data]
volumes: { <container>: {} } Volume anonyme volumes: { /app/data: {} }
volumes: { <container>: { ro: true } } Mount en lecture seule volumes: { /data: { ro: true } }
volumes: { <container>: { consistency: <mode> } } Mode de cohérence (macOS/Windows seulement) volumes: { /data: { consistency: delegated } }
tmpfs: [<path>] Monter un système de fichiers temporaire tmpfs: [/tmp]

Note : Définissez les volumes nommés au niveau supérieur :

volumes:
  my_data:
    driver: local

Limites de ressources

Clé Objectif Exemple
cpus: <float> Limiter les cœurs CPU (ex: 0.5 pour un demi-cœur) cpus: 2
cpu_shares: <int> Poids de partage CPU (priorité relative) cpu_shares: 512
mem_limit: <value> Limiter la mémoire (ex: 512m, 1g) mem_limit: 512m
memswap_limit: <value> Limiter mémoire + swap memswap_limit: 1g
mem_reservation: <value> Limite mémoire souple (permet de dépasser si l’espace disponible) mem_reservation: 256m

Vérifications de santé

Clé Objectif Exemple
healthcheck: { test: [CMD, curl, -f, 'http://localhost/health'] } Définir une commande de vérification de santé (voir ci-dessous)
healthcheck: { test: CMD curl -f http://localhost/health } Vérification de santé en tant que chaîne healthcheck: { test: CMD curl -f http://localhost/health }
healthcheck: { test: CMD-SHELL, 'pg_isready -U postgres' } Vérification de santé avec shell (voir ci-dessous)
healthcheck: { interval: 30s } Fréquence d’exécution (par défaut : 30s) interval: 30s
healthcheck: { timeout: 5s } Timeout pour la vérification (par défaut : 30s) timeout: 5s
healthcheck: { start_period: 10s } Période de grâce avant la première vérification (par défaut : 0s) start_period: 10s
healthcheck: { retries: 3 } Échecs consécutifs avant de marquer comme unhealthy (par défaut : 3) retries: 3
healthcheck: disable: true Désactiver la vérification de santé (si héritée de l’image) disable: true

Exemple complet :

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
  interval: 30s
  timeout: 5s
  start_period: 10s
  retries: 3

Dépendances et ordre de démarrage

Clé Objectif Exemple
depends_on: [<service>] Attendre que les services démarrent (pas de vérification de préparation) depends_on: [db, cache]
depends_on: { <service>: { condition: service_started } } Attendre que le service démarre depends_on: { db: { condition: service_started } }
depends_on: { <service>: { condition: service_healthy } } Attendre que le service soit healthy depends_on: { db: { condition: service_healthy } }
depends_on: { <service>: { condition: service_completed_successfully } } Attendre que le service se termine avec succès (jobs uniques) depends_on: { migration: { condition: service_completed_successfully } }

Attention : condition: service_healthy requiert que le service ait une healthcheck. Sans cela, la condition échoue immédiatement.

Exemple complet :

services:
  web:
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started

Sécurité : secrets et configs

Clé Objectif Exemple
secrets: [<name>] Monter un fichier secret dans /run/secrets/<name> secrets: [db_password]
configs: [<name>] Monter un fichier config dans / configs: [nginx_config]

Définition au niveau supérieur :

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

configs:
  nginx_config:
    file: ./nginx.conf

Accès dans le conteneur :

# Dans le shell : cat /run/secrets/db_password

Profiles

Les profiles vous permettent d’inclure des services de manière conditionnelle.

services:
  web:
    image: nginx:latest
    # Toujours inclus

  debug:
    image: busybox:latest
    profiles: [debug]
    # Inclus seulement avec --profile debug

  monitoring:
    image: prom/prometheus:latest
    profiles: [monitoring, prod]
    # Inclus avec --profile monitoring OU --profile prod

Usage :

docker compose up                        # Inclure seulement les services sans profiles
docker compose --profile debug up        # Inclure web + debug
docker compose --profile monitoring up   # Inclure web + monitoring
docker compose --profile debug --profile monitoring up  # Inclure les trois

Réseaux (niveau supérieur)

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    driver_opts:
      com.docker.network.bridge.name: br0

Usage dans les services :

services:
  web:
    networks: [frontend, backend]
  db:
    networks: [backend]

Volumes (niveau supérieur)

volumes:
  db_data:
    driver: local
  shared_cache:
    driver: local
    driver_opts:
      type: tmpfs
      device: tmpfs

Fichiers override

Docker Compose charge automatiquement docker-compose.override.yaml et le fusionne avec compose.yaml.

compose.yaml (production) :

services:
  web:
    image: myapp:latest
    environment:
      LOG_LEVEL: warn

docker-compose.override.yaml (développement local) :

services:
  web:
    build: .
    ports:
      - "8000:8000"
    environment:
      LOG_LEVEL: debug

Résultat lors de l’exécution de docker compose up :
– L’image est construite à partir de ./Dockerfile (remplace image: myapp:latest)
– Le port 8000 est exposé sur l’hôte
– LOG_LEVEL est défini sur debug
– Le mapping de port et LOG_LEVEL sont fusionnés

Fichier override explicite :

docker compose -f compose.yaml -f compose.prod.yaml up

Commandes CLI

Commande Objectif Exemple
docker compose up Créer et démarrer tous les services docker compose up
docker compose up -d Démarrer les services en mode détaché (arrière-plan) docker compose up -d
docker compose up -d --scale web=3 Mettre à l’échelle un service à N réplicas docker compose up -d --scale web=3
docker compose down Arrêter et supprimer tous les services, réseaux (garde les volumes) docker compose down
docker compose down -v Arrêter et supprimer services, réseaux, ET volumes docker compose down -v
docker compose down --rmi all Supprimer services et supprimer toutes les images docker compose down --rmi all
docker compose down --remove-orphans Supprimer les services non présents dans le fichier Compose docker compose down --remove-orphans
docker compose ps Lister les services en cours d’exécution docker compose ps
docker compose logs Afficher les logs de tous les services docker compose logs
docker compose logs -f Stream les logs en continu (suivi) docker compose logs -f
docker compose logs -f <service> Stream les logs d’un service docker compose logs -f web
docker compose logs --tail 50 <service> Afficher les 50 dernières lignes d’un service docker compose logs --tail 50 web
docker compose exec <service> <command> Exécuter une commande à l’intérieur d’un service docker compose exec web bash
docker compose exec -it <service> bash Exécuter bash de manière interactive à l’intérieur d’un service docker compose exec -it db psql -U postgres
docker compose exec -u <user> <service> <command> Exécuter en tant qu’utilisateur spécifique docker compose exec -u appuser web whoami
docker compose pull Extraire les dernières images pour tous les services docker compose pull
docker compose build Construire toutes les images (si build: est spécifié) docker compose build
docker compose build --no-cache <service> Reconstruire sans cache docker compose build --no-cache web
docker compose start Démarrer les services arrêtés docker compose start
docker compose stop Arrêter les services en cours d’exécution docker compose stop
docker compose stop <service> Arrêter un service spécifique docker compose stop web
docker compose restart Redémarrer tous les services docker compose restart
docker compose restart <service> Redémarrer un service spécifique docker compose restart web
docker compose pause Mettre en pause tous les services docker compose pause
docker compose unpause Reprendre les services en pause docker compose unpause
docker compose config Valider et imprimer la config Compose finale docker compose config
docker compose config --resolve-image-digests Résoudre les digests d’images (utile pour la reproductibilité) docker compose config --resolve-image-digests
docker compose watch Surveiller les changements et synchroniser/reconstruire les services (Compose 2.22+) docker compose watch
docker compose version Afficher la version de Docker Compose docker compose version
docker compose -f <file> <command> Spécifier explicitement un fichier Compose docker compose -f docker-compose.prod.yaml up
docker compose --project-name <name> <command> Utiliser un nom de projet personnalisé (par défaut : nom du répertoire) docker compose --project-name myapp up

Patterns à réutiliser

# Développement avec fichier override
# compose.yaml : configuration de production
# docker-compose.override.yaml : ajustements dev locaux

# Base de données avec healthcheck et depends_on
services:
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: secret
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
  web:
    depends_on:
      db:
        condition: service_healthy

# Application multi-niveaux
services:
  web:
    networks: [frontend, backend]
  cache:
    networks: [backend]
  db:
    networks: [backend]

# Charger l'environnement à partir d'un fichier avec remplacements
services:
  app:
    env_file: .env
    environment:
      LOG_LEVEL: debug  # Remplacer depuis .env

# Profiles pour les services optionnels
  monitoring:
    profiles: [monitoring]
  debug:
    profiles: [debug]

# Utiliser compose watch pour le rechargement en direct (Compose 2.22+)
# docker compose watch
watch:
  - path: ./src
    action: sync
    target: /app/src
  - path: ./requirements.txt
    action: rebuild

FAQ

Quelle est la différence entre docker-compose.yml et compose.yaml ?

Les deux sont supportés. Docker préfère compose.yaml (sans tiret). Les deux sont équivalents ; choisissez une convention et tenez-vous-y. La documentation moderne utilise compose.yaml.

Comment définir des variables d’environnement dans Docker Compose ?

Utilisez la clé environment dans un service, ou chargez à partir d’un fichier avec env_file: .env. Les variables peuvent être codées en dur, à partir du shell hôte (${VAR_NAME}), ou à partir de fichiers .env. Utilisez les secrets pour les valeurs sensibles.

Comment m’assurer qu’un service démarre avant un autre ?

Utilisez depends_on: db: condition: service_healthy (requiert une HEALTHCHECK). Pour juste l’ordre de démarrage sans validation, utilisez la forme courte depends_on: [db] ; elle ordonne seulement le démarrage et n’attend pas la préparation.

Comment utiliser les fichiers override Docker Compose ?

Créez docker-compose.override.yaml dans le même répertoire. Compose le charge automatiquement et le fusionne avec compose.yaml. Remplacez des services spécifiques sans éditer le fichier principal. Utile pour le développement local vs. la production.

Que sont les profiles Docker Compose ?

Les profiles vous permettent d’inclure des services de manière conditionnelle. Définissez profiles: [debug] sur un service, puis utilisez docker compose --profile debug up pour l’inclure. Utile pour les services de débogage optionnels ou les piles de monitoring.

Comment ce guide a été vérifié

Rédigé à la main à partir de la documentation officielle, chaque commande revérifiée, puis relu une seconde fois avant publication. Dernière relecture le .

Sources officielles consultées pour cet article

Share.

Les commentaires sont fermés.