nebino

Docker Compose : structurer une stack proprement

20 octobre 2026

Un fichier Compose lisible et sûr tient à quelques habitudes : images légères, réseaux dédiés, volumes nommés, limites de ressources et configuration factorisée.

Un exemple commenté

x-common: &common
  restart: unless-stopped
  networks: [backend]
  deploy:
    resources:
      limits:
        cpus: "0.50"
        memory: 256M

services:
  api:
    <<: *common
    image: example/api:1.0
    ports:
      - "127.0.0.1:8080:8080"
    depends_on:
      db:
        condition: service_healthy

  db:
    <<: *common
    image: postgres:16-alpine
    environment:
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    secrets: [db_password]
    volumes:
      - db-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      retries: 5

networks:
  backend:

volumes:
  db-data:

secrets:
  db_password:
    file: ./db_password.txt

Ce que fait ce fichier

  • Ancres YAML : x-common regroupe la politique de redémarrage, le réseau et les limites, et <<: *common la réutilise sans répétition.
  • Réseau dédié : les services se joignent par leur nom (db) sur le réseau backend. Rien n’est publié par défaut, et seul api l’est, sur 127.0.0.1 pour rester local.
  • Volume nommé : les données de db survivent à la recréation du conteneur.
  • Healthcheck et depends_on : api attend que la base accepte réellement des connexions, pas seulement que son conteneur soit démarré.
  • Limites de ressources : CPU et mémoire plafonnés pour qu’un service défaillant n’épuise pas la machine.
  • Secret par fichier : un mot de passe passé en variable d’environnement est visible avec docker inspect, pas un secret monté en fichier.

Côté image

  • Les variantes Alpine (postgres:16-alpine) sont légères, mais reposent sur musl plutôt que glibc : certains binaires précompilés n’y fonctionnent pas.
  • Un service qui écoute sur 127.0.0.1 dans son conteneur n’est pas joignable depuis l’extérieur du conteneur : il doit écouter sur 0.0.0.0 (par exemple ENV HOST=0.0.0.0), puis le port est publié côté hôte sur l’interface voulue.
  • Les labels OCI (org.opencontainers.image.*) documentent l’origine et la version d’une image.

Aller plus loin

Une stack de monitoring (Prometheus et Grafana) se branche de la même façon, sur un réseau partagé avec les services à observer.

Voir aussi : la plateforme conteneurisée avec monitoring, le tableau de bord, orchestré avec Docker Compose

Sources

Retour au blog