Docker Compose en 2026 : Applications Multi-Conteneurs, Réseau et Questions d'Entretien DevOps

Guide complet sur Docker Compose en 2026 couvrant les applications multi-conteneurs, la configuration réseau avancée, et les questions fréquentes en entretien DevOps.

Docker Compose Multi-Container Tutorial 2026

Docker Compose demeure l'outil de référence pour définir et exécuter des applications Docker multi-conteneurs en 2026. Que ce soit pour orchestrer un environnement de développement local ou se préparer à un entretien DevOps, la maîtrise du réseau Compose, des dépendances de services et des patterns de production distingue les ingénieurs juniors des praticiens seniors.

Point Clé

Docker Compose utilise un format YAML déclaratif pour définir les services, réseaux et volumes dans un fichier unique. L'exécution de docker compose up lance l'ensemble de la pile applicative avec un réseau isolé et un stockage persistant.

Comprendre l'Architecture de Docker Compose

Docker Compose fonctionne selon un principe simple : définir les services de l'application dans un fichier compose.yaml (la convention de nommage moderne remplaçant docker-compose.yml), et Compose gère la création des conteneurs, le réseau et la gestion du cycle de vie.

La spécification Docker Compose définit trois concepts fondamentaux :

  • Services : Configurations de conteneurs incluant image, contexte de build, variables d'environnement et limites de ressources
  • Réseaux : Canaux de communication isolés entre les services
  • Volumes : Stockage de données persistantes survivant aux redémarrages des conteneurs
yaml
# compose.yaml
services:
  api:
    build: ./api
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://db:5432/app
    depends_on:
      db:
        condition: service_healthy
    networks:
      - backend

  db:
    image: postgres:16
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=app
      - POSTGRES_PASSWORD_FILE=/run/secrets/db_password
    secrets:
      - db_password
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5
    networks:
      - backend

networks:
  backend:
    driver: bridge

volumes:
  postgres_data:

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

Cette configuration illustre plusieurs patterns prêts pour la production : les health checks pour l'ordonnancement des dépendances, les secrets Docker pour les données sensibles, les volumes nommés pour la persistance, et les définitions de réseau explicites.

Réseau Docker Compose en Profondeur

Par défaut, Compose crée un réseau unique pour l'application. Tous les services rejoignent ce réseau et peuvent se joindre mutuellement en utilisant le nom du service comme hostname. Comprendre ce modèle réseau est fondamental pour une migration vers Kubernetes ultérieure.

yaml
# compose.yaml
services:
  frontend:
    build: ./frontend
    ports:
      - "80:80"
    networks:
      - frontend-net
      - backend-net

  api:
    build: ./api
    networks:
      - backend-net

  cache:
    image: redis:7-alpine
    networks:
      - backend-net

  db:
    image: postgres:16
    networks:
      - backend-net

networks:
  frontend-net:
    driver: bridge
  backend-net:
    driver: bridge
    internal: true

Le flag internal: true empêche le réseau backend d'accéder à Internet externe. Le service frontend fait le pont entre les deux réseaux, agissant comme unique point d'entrée. Cette segmentation réseau reflète les pratiques de sécurité en production.

Résolution DNS

Le serveur DNS embarqué de Docker résout automatiquement les noms de services. Le service api atteint la base de données à db:5432 sans aucune configuration IP manuelle.

Builds Multi-Étapes avec Compose

Les images de production doivent être minimales. Les builds multi-étapes combinés aux profils Compose permettent différentes configurations pour le développement et la production.

dockerfile
# api/Dockerfile
# Étape 1: Build
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Étape 2: Production
FROM node:22-alpine AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./
USER node
EXPOSE 3000
CMD ["node", "dist/index.js"]

# Étape 3: Développement
FROM node:22-alpine AS development
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
USER node
CMD ["npm", "run", "dev"]
yaml
# compose.yaml
services:
  api:
    build:
      context: ./api
      target: ${BUILD_TARGET:-production}
    volumes:
      - ${API_VOLUMES:-./api/dist:/app/dist:ro}
    profiles:
      - ${COMPOSE_PROFILES:-prod}

L'exécution de BUILD_TARGET=development COMPOSE_PROFILES=dev docker compose up démarre la configuration de développement avec rechargement à chaud.

Dépendances de Services et Health Checks

La directive depends_on contrôle l'ordre de démarrage, mais les conteneurs qui démarrent ne signifie pas que les services sont prêts. Les health checks résolvent ce problème de timing—un pattern fréquemment abordé en entretiens DevOps.

yaml
# compose.yaml
services:
  api:
    build: ./api
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started
      migrations:
        condition: service_completed_successfully

  migrations:
    build: ./api
    command: npm run migrate
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres:16
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 3s
      retries: 5
      start_period: 10s

  cache:
    image: redis:7-alpine
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 3

Trois conditions de dépendance existent :

  • service_started : Par défaut, le conteneur a démarré
  • service_healthy : Le health check réussit
  • service_completed_successfully : Le conteneur termine avec le code 0 (pour les conteneurs d'initialisation)

Prêt à réussir tes entretiens DevOps ?

Entraîne-toi avec nos simulateurs interactifs, fiches express et tests techniques.

Docker Compose pour le Développement Local

Les environnements de développement bénéficient des bind mounts, des overrides d'environnement et des outils de débogage. Le fichier compose.override.yaml fusionne automatiquement avec compose.yaml.

yaml
# compose.yaml (configuration de base)
services:
  api:
    build: ./api
    environment:
      - NODE_ENV=production

  db:
    image: postgres:16
yaml
# compose.override.yaml (overrides de développement)
services:
  api:
    build:
      target: development
    volumes:
      - ./api:/app
      - /app/node_modules
    environment:
      - NODE_ENV=development
      - DEBUG=app:*
    ports:
      - "9229:9229"

  db:
    ports:
      - "5432:5432"

Le volume anonyme /app/node_modules empêche le node_modules de l'hôte d'écraser les dépendances installées du conteneur.

Patterns de Déploiement en Production

Docker Compose fonctionne pour les déploiements production mono-hôte. Pour l'orchestration multi-hôtes, Kubernetes avec Helm offre une meilleure mise à l'échelle, mais Compose reste viable pour les petites applications.

yaml
# compose.prod.yaml
services:
  api:
    image: registry.example.com/api:${VERSION:-latest}
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: "0.5"
          memory: 512M
        reservations:
          cpus: "0.25"
          memory: 256M
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./certs:/etc/nginx/certs:ro
    depends_on:
      - api

La clé deploy configure les limites de ressources, le nombre de réplicas et les politiques de redémarrage. L'exécution de docker compose -f compose.prod.yaml up -d démarre la pile de production en mode détaché.

Variables d'Environnement et Gestion des Secrets

La configuration sensible nécessite une gestion appropriée. Docker Compose supporte plusieurs approches, des fichiers .env aux secrets Docker.

bash
# .env
POSTGRES_PASSWORD=dev_password_only
API_SECRET_KEY=local_dev_key
yaml
# compose.yaml
services:
  api:
    environment:
      - API_SECRET_KEY  # Hérite du shell ou .env
      - DATABASE_URL=postgres://user:${POSTGRES_PASSWORD}@db:5432/app
    env_file:
      - ./config/api.env

Pour la production, les secrets Docker offrent une meilleure sécurité en montant les données sensibles comme fichiers plutôt que variables d'environnement :

yaml
# compose.prod.yaml
services:
  api:
    secrets:
      - api_key
      - db_password
    environment:
      - API_KEY_FILE=/run/secrets/api_key

secrets:
  api_key:
    external: true
  db_password:
    file: ./secrets/db_password.txt
Note de Sécurité

Ne jamais commiter de fichiers .env contenant des secrets de production dans le contrôle de version. Utiliser des solutions de gestion de secrets externes comme HashiCorp Vault ou les solutions des fournisseurs cloud pour les déploiements production.

Questions Fréquentes d'Entretien DevOps sur Docker Compose

Les recruteurs testent la compréhension des concepts Compose à travers des scénarios pratiques. Ces questions apparaissent fréquemment dans les entretiens DevOps et ingénierie de plateforme.

Q : Comment les conteneurs d'un réseau Compose communiquent-ils ?

Docker crée un réseau bridge dédié pour chaque projet Compose. Les services communiquent en utilisant leurs noms de service comme hostnames. Le serveur DNS embarqué résout ces noms en adresses IP de conteneurs. Le trafic externe atteint les services uniquement via les ports explicitement publiés.

Q : Que se passe-t-il lors de l'exécution de docker compose up avec des conteneurs existants ?

Compose compare la configuration actuelle aux conteneurs en cours d'exécution. Les services inchangés continuent de tourner. Les services modifiés sont recréés avec les nouveaux paramètres. Les nouveaux services démarrent à neuf. Les services supprimés sont arrêtés et supprimés.

Q : Comment gérer les migrations de base de données dans Compose ?

Deux patterns existent. Premièrement, utiliser un conteneur d'initialisation avec la dépendance service_completed_successfully :

yaml
services:
  migrate:
    image: api:latest
    command: npm run migrate
    depends_on:
      db:
        condition: service_healthy

  api:
    depends_on:
      migrate:
        condition: service_completed_successfully

Deuxièmement, inclure la logique de migration dans le script de démarrage de l'application, vérifiant et appliquant les migrations en attente avant d'accepter le trafic.

Q : Quelle différence entre les volumes et les bind mounts ?

Les volumes nommés sont gérés par Docker, stockés dans /var/lib/docker/volumes, et portables entre les hôtes. Les bind mounts mappent directement les répertoires hôte dans les conteneurs, utiles pour le développement mais dépendants de l'environnement. Les volumes supportent des drivers pour le stockage distant comme NFS ou le stockage bloc cloud.

Q : Quelle différence entre docker-compose et docker compose ?

Le docker-compose avec tiret était l'outil standalone V1 basé sur Python, maintenant déprécié. Le docker compose avec espace est l'implémentation V2 basée sur Go intégrée au CLI Docker. V2 est plus rapide, supporte entièrement la Spécification Compose, et reçoit un développement actif.

Débogage des Applications Compose

Le dépannage d'applications conteneurisées nécessite des techniques spécifiques. Ces commandes révèlent ce qui se passe à l'intérieur de la pile Compose :

bash
# Voir les logs de tous les services
docker compose logs -f

# Logs d'un service spécifique avec timestamps
docker compose logs -f --timestamps api

# Exécuter une commande dans un conteneur en cours d'exécution
docker compose exec api sh

# Exécuter une commande ponctuelle (démarre un nouveau conteneur)
docker compose run --rm api npm test

# Voir l'utilisation des ressources
docker compose top
docker stats

# Inspecter la configuration réseau
docker network inspect project_backend

# Valider le fichier compose
docker compose config

La commande docker compose config fusionne tous les fichiers compose et affiche la configuration finale—invaluable pour déboguer les problèmes d'interpolation de variables.

Conclusion

  • Docker Compose définit les applications multi-conteneurs dans un seul fichier YAML avec services, réseaux et volumes
  • Les services communiquent via DNS en utilisant les noms de service comme hostnames au sein du réseau bridge par défaut
  • Les health checks avec conditions service_healthy assurent un ordonnancement de démarrage correct
  • Utiliser compose.override.yaml pour les paramètres spécifiques au développement comme les bind mounts et les ports de débogage
  • Les déploiements production bénéficient des limites de ressources, politiques de redémarrage et secrets Docker pour les données sensibles
  • Le CLI docker compose (V2) remplace le déprécié docker-compose (V1) avec de meilleures performances et fonctionnalités

Passe à la pratique !

Teste tes connaissances avec nos simulateurs d'entretien et tests techniques.

Tags

#docker
#docker-compose
#devops
#containers
#networking

Partager

Articles similaires