Niveau 🟡 intermédiaire
Durée estimée : 25 min · Prérequis : Docker en profondeur
compose.yaml ligne par ligne et savoir ce que chaque clé faitUn fichier compose.yaml, c'est la fiche de montage d'un meuble en kit : chaque ligne précise
une pièce (l'image), où elle se fixe (les volumes), à quoi elle se connecte (le réseau), et le
comportement attendu si quelque chose tombe (la politique de redémarrage). Une fois cette fiche
écrite, le montage devient reproductible à l'identique, autant de fois que nécessaire.
Docker Compose décrit, dans un seul fichier YAML, un ou plusieurs conteneurs qui forment un
« stack » cohérent — plutôt que de taper une longue commande docker run à chaque service, on
déclare l'état voulu une fois, et Compose se charge de le réaliser (docker compose up).
Décortiquons un exemple réel, un stack à un seul service, simplifié et anonymisé :
services:
mon-service:
image: organisation/mon-service:1.23.4
container_name: mon-service
restart: unless-stopped
networks:
- npm_proxy
ports:
- 127.0.0.1:3001:3001
volumes:
- /srv/docker/mon-service:/app/data
networks:
npm_proxy:
external: true
Ligne par ligne :
services: — introduit la liste des conteneurs de ce stack (un seul ici).image: organisation/mon-service:1.23.4 — le nom de l'image et son tag figé (1.23.4,latest). Un tag figé garantit qu'une mise à jour ne se produit que si on la décidecontainer_name: mon-service — un nom fixe et lisible pour ce conteneur, plutôt que le nomrestart: unless-stopped — la politique de redémarrage : ce conteneur redémarrenetworks: - npm_proxy — connecte ce conteneur au réseau nommé npm_proxy, lui permettantports: - 127.0.0.1:3001:3001 — publie le port 3001 du conteneur, mais uniquement sur127.0.0.1 (la machine elle-même), jamais sur le réseau. C'est la parade au piègeufw vue en M2 : seul le reverse proxy, sur la mêmevolumes: - /srv/docker/mon-service:/app/data — un bind mount : le dossier/srv/docker/mon-service de la machine hôte est monté dans le conteneur, à l'emplacement oùnetworks: npm_proxy: external: true (en bas du fichier) — déclare que ce réseau n'est pas🧪 Concrètement, sur notre exemple : ce squelette correspond, dans les grandes lignes, au
stack réel d'un des services de supervision de ce serveur — un tag figé (jamaislatest), un
port publié uniquement en local, un bind mount vers/srv/docker/<service>, et le réseau
npm_proxypartagé enexternal: true. Cette structure se répète, quasi identique, pour
chaque service simple à un seul conteneur de ce dépôt — une convention cohérente plutôt qu'un
stack réinventé à chaque fois.
Chaque clé du fichier correspond à une flèche du schéma : le port en boucle locale limite l'accès
réseau direct, le bind mount fixe où vivent les données, le réseau externe relie ce conteneur au
reste du système.
docker compose config
# Valide la syntaxe d'un compose.yaml et affiche sa version "résolue"
# (variables d'environnement substituées) -- sans rien démarrer
docker compose up -d
# Démarre le stack en arrière-plan (-d, "detached")
docker compose logs -f mon-service
# Suit les journaux du service en continu (-f, "follow") -- le premier
# réflexe si un conteneur ne se comporte pas comme attendu
docker compose down
# Arrête et supprime les conteneurs du stack (les volumes/bind mounts
# et donc les données, eux, survivent -- sauf option -v explicite)
docker compose config && docker compose up -d && docker compose ps
docker compose ps doit afficher le service avec un état running (ou Up) — confirmation que
le fichier est syntaxiquement valide et que le conteneur a effectivement démarré.
| Symptôme | Cause probable | Solution |
|---|---|---|
| Une mise à jour d'image se déclenche sans qu'on l'ait demandée | Tag latest utilisé plutôt qu'un tag figé |
Toujours épingler une version précise (image:1.23.4), jamais latest, pour un service qu'on ne veut pas voir changer tout seul |
network npm_proxy declared as external, but could not be found |
Le réseau externe n'a pas été créé au préalable | Créer le réseau manuellement une fois (docker network create npm_proxy) avant tout stack qui le référence |
| Service joignable depuis tout le réseau local alors que ce n'était pas voulu | Port publié sans restriction (3001:3001 plutôt que 127.0.0.1:3001:3001) |
Toujours préciser 127.0.0.1: devant un port publié qui ne doit être accessible que localement |
latest ne devrait jamais êtrerestart: unless-stopped redémarre automatiquement après une panne, sans relancer un service127.0.0.1 uniquement, avec un reverse proxy en façade, limite fortementexternal: true référence un réseau créé en dehors de ce stack — indispensable pourParce qu'il pointe vers une version qui change dans le temps — une mise à jour peut alors se
produire silencieusement au prochain docker compose pull/up, sans décision explicite.
Compose tente de créer son propre réseau, potentiellement en conflit ou isolé du réseau partagé
existant — les autres stacks ne pourraient plus joindre ce conteneur par son nom comme prévu.
Pour limiter l'accès à ce port à la machine elle-même uniquement — pertinent quand un reverse
proxy sur la même machine gère déjà l'accès réseau réel, et qu'on veut éviter le piège
Docker/ufw vu en M2.
Écris un compose.yaml minimal pour un service fictif de ton choix, avec : un tag d'image figé,
une politique restart: unless-stopped, un port publié en 127.0.0.1 uniquement, et un bind
mount vers un chemin de ton choix. Valide-le avec docker compose config.
Docker Compose ·
stack ·
tag (Docker)
Cette formation est proposée par Deladev, studio web de Loïc D. — création de sites et d'applications, accompagnement et formation sur mesure.
Les projets réalisés · Prestations et tarifs · Le blog tech · Me contacter
Écrite par Loïc D. avec l'assistance de Claude (Anthropic) — un travail à deux.
© 2026 Deladev — publiée sous licence CC BY-NC-ND 4.0. Vous pouvez la lire, y renvoyer par un lien, la partager et la citer en créditant la source. La revendre, l'utiliser dans une prestation ou une formation payante, la republier même partiellement ailleurs, en diffuser une version modifiée ou l'exploiter pour entraîner un modèle d'IA nécessitent une autorisation écrite — pour un usage interne en entreprise, c'est souvent oui, il suffit de demander.