Docker Compose : orchestrer une stack locale
Décrivez une stack locale (API, base de données, reverse proxy) dans un seul fichier Compose : services, réseaux, volumes, healthchecks et commandes du quotidien.

Décrivez une stack locale (API, base de données, reverse proxy) dans un seul fichier Compose : services, réseaux, volumes, healthchecks et commandes du quotidien.

Un conteneur isolé, c’est un bon début. Mais une application web, c’est presque toujours une stack : une API, une base de données, parfois un reverse proxy ou un worker. Docker Compose décrit ces services dans un fichier YAML, les démarre ensemble, leur fournit un réseau, des volumes et des variables d’environnement. Le tout avec une commande : docker compose up.
Ce guide montre comment monter une stack locale crédible, sans transformer votre portable en cluster Kubernetes.
Compose lit un fichier, le plus souvent compose.yaml, qui déclare :
Les commandes de base :
# Démarrer tous les services en arrière-plan
docker compose up -d
# Lister l'état des services
docker compose ps
# Suivre les journaux du service api
docker compose logs -f api
# Arrêter et supprimer les conteneurs du projet
docker compose down
L’option -d détache les conteneurs du terminal. La commande down supprime les conteneurs et le réseau du projet, mais conserve les volumes nommés, sauf si vous ajoutez --volumes. La documentation officielle de Compose et la référence du fichier Compose détaillent chaque option.
Voici l’arborescence du projet :
projet/
compose.yaml
api/
Dockerfile
package.json
server.js
Caddyfile
Et un compose.yaml simplifié :
services:
db:
image: postgres:16
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: app
POSTGRES_DB: app
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d app"]
interval: 5s
timeout: 5s
retries: 10
api:
build: ./api
environment:
DATABASE_URL: postgres://app:app@db:5432/app
NODE_ENV: development
volumes:
# Le code est monté pour le rechargement à chaud
- ./api:/usr/src/app
# Volume anonyme : conserve les node_modules du conteneur
- /usr/src/app/node_modules
ports:
- "3000:3000"
depends_on:
db:
condition: service_healthy
proxy:
image: caddy:2
ports:
- "8080:80"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
depends_on:
- api
volumes:
pgdata:
Le Caddyfile minimal :
:80 {
reverse_proxy api:3000
}
Quelques points à remarquer :
db désigne le service Postgres sur le réseau Compose ;DATABASE_URL utilise db et non localhost : dans un conteneur, localhost désigne le conteneur lui-même ;pgdata assure la persistance des données ;depends_on associé à un healthcheck fait attendre l’API jusqu’à ce que la base soit réellement prête, et pas seulement démarrée ;node_modules évite d’écraser les modules compilés pour Linux par ceux de votre machine.Ouvrez ensuite http://localhost:8080 : le proxy relaie vers l’API. En équipe, ce socle remplace dix README contradictoires. Si vous souhaitez le déléguer, l’agence Yunt peut livrer ce type de stack avec le dépôt.
docker compose up -d --build
docker compose stop
docker compose start
docker compose down
L’option --build reconstruit les images si un Dockerfile a changé. Pour comprendre ce que contient ./api/Dockerfile, reportez-vous à l’article Dockerfile expliqué : construire une image web.
docker compose logs -f --tail=100
docker compose exec api sh
docker compose exec db psql -U app -d app
exec ouvre une commande dans un service déjà lancé, tandis que run crée un conteneur ponctuel.
docker compose exec api npm run migrate
docker compose exec api npm run seed
Préférez des scripts de données idempotents, que l’on peut rejouer sans casser la base, à un gros export SQL opaque.
docker compose down --volumes
Cette commande efface les volumes nommés du projet. Idéale pour repartir propre, elle est dangereuse si vous y conserviez des données uniques sans sauvegarde.
Dans Compose, les services se joignent par leur nom de service. Depuis votre machine (navigateur, client SQL), vous passez par les ports publiés. Depuis le conteneur api, localhost:5432 ne pointe pas vers Postgres : utilisez db:5432. Cette confusion est l’erreur la plus fréquente des débutants.
Compose charge un fichier .env voisin pour l’interpolation de variables :
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
Trois habitudes à adopter : ignorer .env dans Git, versionner un .env.example, et ne jamais mettre de secret de production « pour tester vite ».
Un fichier Compose utile est un contrat :
compose.yaml (socle), compose.override.yaml (développement local, fusionné automatiquement) et un fichier dédié aux tests en CI.Un premier démarrage peut alors tenir en trois commandes :
cp .env.example .env
docker compose up -d --build
docker compose exec api npm run seed
Dès qu’il y a des files de tâches (envoi d’e-mails, miniatures), un service worker réutilise l’image de l’API avec une autre commande :
worker:
build: ./api
command: ["node", "worker.js"]
environment:
DATABASE_URL: postgres://app:app@db:5432/app
depends_on:
db:
condition: service_healthy
Pour des outils occasionnels comme Mailpit (réception d’e-mails de test), les profils permettent de ne les démarrer qu’à la demande :
mail:
image: axllent/mailpit
ports:
- "8025:8025"
- "1025:1025"
profiles: ["tools"]
docker compose --profile tools up -d
--build ou docker compose build.-p permet d’isoler les noms de projets.volumes.depends_on sans healthcheck : un conteneur « démarré » ne signifie pas que Postgres accepte des connexions.Quand un bug n’apparaît « que dans Compose », comparez d’abord les variables d’environnement et les noms d’hôtes. Enfin, ne publiez jamais tel quel un fichier Compose de développement (mots de passe triviaux, code monté, mode debug) sur Internet. Pour une base solide côté production, consultez les bonnes pratiques Docker pour projets web.
Compose reste excellent en local et pour de petits déploiements. Il montre ses limites quand vous avez besoin de :
Kubernetes ou une plateforme managée prennent alors le relais. Beaucoup d’équipes web se contentent longtemps de Compose en local et d’un hébergeur qui gère l’exécution. Choisir l’outil au bon moment évite la sur-ingénierie. Pour situer Docker par rapport à la virtualisation, lisez À quoi sert Docker pour un développeur web.
Docker Compose orchestre une stack locale : services, réseau, volumes, variables et journaux. Pour un développeur web, c’est souvent l’outil qui rend Docker réellement utile au quotidien, bien au-delà d’une démonstration avec Nginx.
Écrivez un compose.yaml minimal (API et base), faites parler l’API avec le nom d’hôte du service, ajoutez un healthcheck et documentez les commandes up, down et seed. Enrichissez ensuite avec un proxy, un worker et des outils. Pour ancrer ces réflexes dans une formation web complète, découvrez Academy Yunt.
Préférez docker compose, le plugin intégré à Docker (version 2). L’ancien binaire docker-compose disparaît peu à peu des tutoriels sérieux.
Non. Compose brille en développement local et pour de petits déploiements. Kubernetes répond à d’autres enjeux d’orchestration à grande échelle.
Oui, avec un volume qui monte le code et un processus de développement (nodemon, Vite…). Gardez une image de production sans ce montage.
C’est utile pour un client SQL installé sur votre machine. Sinon, le réseau interne de Compose suffit.
Évitez les migrations destructives automatiques au démarrage. Préférez une commande explicite ou une étape de votre pipeline de déploiement.