Si vous lisez cet article, vous avez certainement une connaissance de cet outil de conteneurisation très populaire dans le monde DevOps : Docker. Mais qu’est alors exactement Docker Compose ? Docker Compose est utilisé pour lancer des applications qui ont besoin de plusieurs conteneurs pour fonctionner, via un fichier YAML.
Il est souvent nécessaire qu’une application ait besoin d’exécuter plusieurs conteneurs pour différentes tâches. Par conséquent, il peut s’avérer complexe de les exécuter séparément, tout en les faisant communiquer les uns aux autres. C’est là que Docker Compose intervient, et va vous faciliter grandement la tâche.
L’orchestration et les différentes actions possibles sont inscrites dans un fichier docker-compose.yml dont nous allons expliquer son fonctionnement plus en détail dans cet article. Cet unique fichier contiendra une multitude d’actions possibles, allant de la construction de vos images Docker, en passant par les connexions et les volumes.
Qu’est-ce que Docker Compose et pourquoi l’utiliser ?

Docker Compose est un outil qui permet de définir et de lancer plusieurs conteneurs Docker en une seule commande. Au lieu d’exécuter plusieurs docker run avec des options complexes, vous décrivez toute votre architecture dans un fichier YAML (nommé docker-compose.yml ou compose.yaml) et démarrez l’ensemble avec docker compose up. C’est la solution officielle pour orchestrer des applications multi-conteneurs en Cloud & Dev sans recourir à un orchestrateur lourd comme Kubernetes.
Dans la majorité des projets réels, une application ne repose pas sur un seul conteneur. Une stack web typique combine par exemple un serveur applicatif, une base de données et un cache. Gérer ces conteneurs séparément, en veillant à leur ordre de démarrage, à leur communication et à la persistance de leurs données, devient rapidement complexe. Docker Compose centralise toute cette configuration dans un fichier unique, versionnable et partageable avec toute l’équipe.
Concrètement, Docker Compose permet de :
- Démarrer, arrêter et reconstruire tous vos services en une seule commande
- Définir les relations et dépendances entre conteneurs (quel service attend quel autre)
- Configurer les réseaux internes pour que les services communiquent entre eux
- Déclarer des volumes pour persister les données en dehors des conteneurs
- Gérer les variables d’environnement et les secrets de façon centralisée
- Consulter l’état et les logs de tous les services en temps réel
- Reproduire un environnement identique sur n’importe quelle machine disposant de Docker
Compose vs sans Compose : quelles différences ?
Pour mesurer l’apport de Docker Compose, il suffit de comparer les deux approches sur un exemple concret : déployer une stack WordPress avec MySQL. Sans Compose, il faut exécuter manuellement chaque commande docker run dans le bon ordre, en mémorisant chaque option (ports, variables d’environnement, réseaux, volumes). La moindre erreur impose de tout recommencer. Et si un collègue souhaite reproduire l’environnement, il faut lui transmettre toutes ces commandes une par une, sans garantie qu’elles correspondent à ce qui tourne réellement.
Avec Docker Compose, la totalité de la configuration est décrite dans un fichier versionné sous Git. N’importe qui peut cloner le dépôt et lancer docker compose up pour obtenir exactement le même environnement, en quelques secondes, sans risque d’oubli ou de divergence.
| Critère | Sans Docker Compose | Avec Docker Compose |
|---|---|---|
| Lancement des services | Plusieurs commandes docker run manuelles | Une seule commande : docker compose up |
| Gestion des dépendances | Ordre d’exécution à gérer manuellement | Déclaré via depends_on dans le fichier YAML |
| Communication entre conteneurs | Configuration réseau manuelle | Réseau commun créé automatiquement |
| Persistance des données | Volumes à déclarer à chaque commande | Volumes définis une fois dans le fichier |
| Reproductibilité | Difficile (commandes à partager) | Totale (fichier YAML versionnable) |
| Arrêt et nettoyage | Chaque conteneur à stopper individuellement | docker compose down arrête tout |
Quand utiliser Docker Compose ?
Docker Compose est l’outil idéal dans les situations suivantes :
- Développement local : reproduire fidèlement un environnement de production sur son poste, avec tous les services nécessaires (base de données, cache, queue de messages, etc.)
- Tests et intégration continue : créer des environnements isolés et reproductibles pour les pipelines CI/CD
- Préproduction : valider une stack complète sur un serveur unique avant de passer en production
- Petits déploiements : héberger une application multi-services sur un seul serveur, sans besoin de haute disponibilité
- Démonstrations et prototypes : partager rapidement une stack fonctionnelle avec une équipe ou un client
En revanche, Docker Compose atteint ses limites dès que les besoins dépassent le cadre d’une seule machine. Si votre application doit répartir la charge sur plusieurs serveurs, se relancer automatiquement en cas de panne matérielle, ou garantir un déploiement sans interruption de service (zero downtime), il faut se tourner vers un vrai orchestrateur : Kubernetes pour les architectures complexes, ou Docker Swarm pour une solution plus simple. La règle pratique est simple : Compose en développement et pour les petits déploiements, un orchestrateur dès que la production exige de la résilience multi-serveurs.
Comment Compose fonctionne-t-il (services, réseaux, volumes) ?
Docker Compose repose sur trois concepts fondamentaux qui structurent toute application multi-conteneurs. Comprendre ces trois briques est indispensable avant d’écrire votre premier fichier docker-compose.yml.
- Les services : un service représente un conteneur et toute sa configuration. C’est l’unité de base dans Docker Compose. Chaque service précise l’image Docker à utiliser, les ports à exposer, les variables d’environnement à injecter, les volumes à monter et les dépendances vis-à-vis des autres services. Quand vous lancez
docker compose up, Compose lit ces définitions et crée les conteneurs correspondants. - Les réseaux : un réseau Docker est un espace de communication isolé dans lequel les conteneurs peuvent échanger des données. Docker Compose crée automatiquement un réseau par défaut pour tous les services d’un même fichier. La résolution DNS y est automatique : chaque service est joignable par son nom (par exemple, un service
wordpresspeut contactermysqlsimplement en utilisantmysqlcomme nom d’hôte, sans connaître son adresse IP). Il est également possible de définir des réseaux personnalisés pour isoler certains services entre eux. - Les volumes : les conteneurs sont éphémères par nature. Lorsqu’un conteneur est supprimé, toutes ses données disparaissent avec lui. Les volumes résolvent ce problème en stockant les données en dehors du conteneur, sur le système de fichiers de l’hôte. Même si le conteneur est recréé, les données du volume sont préservées. C’est indispensable pour toute base de données ou tout fichier devant survivre aux redémarrages.
Ces trois concepts forment l’ossature logique de n’importe quelle stack Compose : les services font tourner le code, les réseaux permettent leur communication, et les volumes assurent la persistance des données. Toute la configuration est rassemblée dans un unique fichier YAML, ce qui rend l’architecture lisible, maintenable et reproductible à l’identique sur n’importe quel environnement.
Installation de Docker Compose

Pour commencer à utiliser Docker Compose, vous devez tout d’abord l’installer sur votre système. Son installation est simple et disponible pour les principales plateformes. Avant de procéder, quelques prérequis sont à respecter :
- Docker Engine installé : Docker Compose fonctionne comme une surcouche à Docker ; le moteur doit donc être présent sur votre machine.
- Privilèges administrateur ou sudo : nécessaires pour l’installation sur Linux.
- Connexion Internet : pour télécharger les paquets ou Docker Desktop selon votre OS.
Quelle version utiliser (V2 plugin vs docker-compose legacy) ?
Il existe deux générations de Docker Compose, et la distinction est importante pour éviter toute confusion dans vos scripts et vos pipelines CI/CD. La première génération, basée sur Python, s’invoque avec docker-compose (V1), tandis que la seconde, basée sur Go, s’utilise comme plugin Docker CLI avec la commande docker compose (V2 et supérieur). Docker Compose V1 a été entièrement retiré en avril 2025. La V1 a atteint sa fin de vie et n’est plus maintenue : si vous utilisez encore docker-compose avec un tiret, vous utilisez un logiciel non supporté.
Docker Compose V2 est intégré directement dans le CLI Docker et s’utilise avec la commande docker compose (avec un espace). Cette intégration améliore les performances et simplifie l’installation. La plupart des fichiers Compose existants fonctionnent sans modification, les principaux changements concernant la dépréciation du champ version et quelques options supprimées.
| Critère | V1 (legacy) | V2 (plugin, recommandé) |
|---|---|---|
| Commande | docker-compose (avec tiret) | docker compose (avec espace) |
| Langage | Python | Go |
| Intégration CLI | Binaire autonome | Plugin natif du CLI Docker |
| Statut | Fin de vie (avril 2025) | Actif, recommandé |
Champ version: dans le YAML | Requis | Déprécié, à supprimer |
Les fichiers Compose modernes commencent directement par services:, sans champ version:. Si vous voyez version: dans un tutoriel, ce tutoriel est probablement obsolète.
Comment l’installer sur macOS, Windows et Linux ?
- macOS : Docker Compose est inclus avec Docker Desktop pour macOS, sans installation séparée nécessaire. Téléchargez Docker Desktop depuis le site officiel de Docker en choisissant la bonne version selon votre processeur (Apple Silicon M1-M5 ou Intel). Lien officiel : docs.docker.com/desktop/install/mac-install/
- Windows : Comme sur macOS, Windows bénéficie de Docker Compose automatiquement via Docker Desktop. Lors de l’installation, assurez-vous que l’option « Use WSL2 instead of Hyper-V » est cochée pour de meilleures performances. Lien officiel : docs.docker.com/desktop/install/windows-install/
- Linux (Ubuntu / Debian) : Sur Linux, la méthode recommandée passe par le dépôt officiel Docker. Installez le plugin Compose via le gestionnaire de paquets :
- Linux (distributions basées sur RPM : CentOS, Fedora, RHEL) :
Sur Linux uniquement, il est également possible d’installer le plugin Compose directement depuis la ligne de commande si Docker Engine et le CLI Docker sont déjà présents. Le plugin est alors installé via le paquet docker-compose-plugin. Pour les cas où le gestionnaire de paquets n’est pas disponible, une installation manuelle reste possible en téléchargeant le binaire depuis le dépôt GitHub officiel de Docker. Lien officiel : docs.docker.com/compose/install/
Comment vérifier l’installation ?
Une fois l’installation terminée, quelques commandes permettent de confirmer que Docker Compose est correctement opérationnel sur votre système.
- Vérifier la version installée : exécutez la commande suivante dans votre terminal.
Une fois Docker Compose installé, cette commande confirme que tout fonctionne correctement. Le numéro de version exact variera selon le moment de l’installation, mais tant que vous voyez v5.0.1 ou plus récent, vous êtes prêt. Notez bien la syntaxe docker compose avec un espace, caractéristique de la V2, et non docker-compose --version de l’ancienne génération.
- Valider un fichier docker-compose.yml : pour vérifier la syntaxe de votre fichier de configuration avant de lancer vos conteneurs, utilisez :
- Diagnostic rapide en cas de problème : si la commande
docker compose versionrenvoie une erreur, vérifiez que Docker Desktop est bien lancé (icône active dans la barre des tâches sur macOS et Windows), ou que le démon Docker est démarré sur Linux avecsudo systemctl start docker. Sur Linux, assurez-vous également que votre utilisateur appartient au groupedockerpour éviter les erreurs de permission.
Comment démarrer rapidement avec Docker Compose ?

Démarrer avec Docker Compose se résume à trois étapes fondamentales : décrire l’environnement de votre application, configurer vos services dans un fichier YAML, puis lancer l’ensemble avec une seule commande. Cette approche, reprise dans toute la documentation officielle, permet à n’importe quel développeur de reproduire un environnement identique en quelques minutes, sans jongler avec de multiples commandes docker run.
- Préparer l’arborescence du projet : créez un dossier dédié contenant au minimum un fichier
docker-compose.ymlet un fichier.envpour vos variables sensibles. - Écrire le fichier docker-compose.yml : décrivez chaque service (image, ports, volumes, variables d’environnement) dans ce fichier YAML unique.
- Lancer l’application : exécutez
docker compose up -ddepuis le dossier du projet. Compose crée les réseaux, les volumes et démarre tous les conteneurs dans le bon ordre.
Quel squelette minimal pour un projet ?
Avant d’écrire la moindre ligne de YAML, il est utile d’adopter une arborescence cohérente. Cette organisation facilite la collaboration en équipe, simplifie la gestion des variables d’environnement et évite de versionner accidentellement des secrets. Voici la structure recommandée pour un projet Docker Compose, quelle que soit sa taille :
mon-projet/: dossier racine du projet, versionné avec Git.mon-projet/src/: code source de l’application, monté en volume lors du développement.mon-projet/docker-compose.yml: fichier de configuration principal décrivant tous les services.mon-projet/.env: variables d’environnement et secrets (à ajouter impérativement dans.gitignore, ne jamais versionner ce fichier).mon-projet/volumes/: dossier optionnel pour les bind mounts locaux (données persistées accessibles directement depuis l’hôte en développement).mon-projet/.gitignore: doit inclure au minimum.envet les dossiers de données sensibles.
En production ou en équipe, vous pouvez compléter cette base avec un docker-compose.override.yml pour les surcharges de développement et un docker-compose.prod.yml pour les paramètres propres à la production.
À quoi ressemble un docker-compose.yml minimal ?
L’exemple ci-dessous illustre un fichier docker-compose.yml minimal avec deux services : un serveur web (Nginx) et une base de données PostgreSQL optionnelle. Chaque ligne importante est commentée pour faciliter la compréhension.
Quelques points clés à retenir sur cet exemple. La clé services définit l’ensemble des conteneurs à créer. La directive ports expose le port 80 du conteneur sur le port 8080 de votre machine, ce qui évite les conflits si d’autres services tournent localement. Le paramètre environment injecte des variables dans le conteneur : plutôt que d’écrire le mot de passe en clair, la syntaxe ${DB_PASSWORD} délègue la valeur au fichier .env. Enfin, les volumes nommés (ici db_data) sont gérés par Docker et survivent à la suppression du conteneur, ce qui est indispensable pour une base de données.
Comment lancer, arrêter et nettoyer ?
Voici les commandes essentielles du cycle de vie d’une application Docker Compose. Elles s’exécutent toutes depuis le dossier contenant votre docker-compose.yml.
| Commande | Description |
|---|---|
docker compose up | Crée et démarre tous les services au premier plan (affiche les logs en direct). |
docker compose up -d | Démarre tous les services en arrière-plan (mode detached, recommandé). |
docker compose up --build | Reconstruit les images avant de démarrer (utile après modification d’un Dockerfile). |
docker compose ps | Liste les conteneurs du projet avec leur statut (running, exited, etc.). |
docker compose logs | Affiche les logs de tous les services. |
docker compose logs -f | Suit les logs en temps réel (équivalent à tail -f). Quitter avec Ctrl+C. |
docker compose down | Arrête et supprime les conteneurs ainsi que les réseaux créés par Compose. |
docker compose down --remove-orphans | Idem, et supprime en plus les conteneurs orphelins (services supprimés du fichier YAML mais encore présents). |
docker compose down -v | Supprime également les volumes nommés. Attention : les données sont définitivement perdues. |
docker compose rm | Supprime les conteneurs arrêtés sans toucher aux volumes ni aux réseaux. |
Quelques pièges courants à connaître avant de commencer. Premièrement, docker compose down ne supprime pas les volumes par défaut : vos données persistent même après l’arrêt, ce qui est un comportement voulu pour les bases de données. Si vous souhaitez repartir d’un état vierge, utilisez explicitement docker compose down -v. Deuxièmement, si vous renommez ou supprimez un service dans votre fichier YAML sans exécuter docker compose down --remove-orphans, l’ancien conteneur continuera de tourner en « orphelin » et consommera des ressources. Troisièmement, depends_on garantit l’ordre de démarrage des conteneurs, mais pas que le service dépendant soit réellement prêt à accepter des connexions : ajoutez un healthcheck pour les dépendances critiques comme une base de données.
Le fichier docker-compose.yml

Ce fichier est le cœur de toute application Docker Compose. Il contient toutes les règles et configurations nécessaires à l’exécution de vos conteneurs : la syntaxe YAML est conçue pour être lisible par un humain tout en restant exploitable par la machine. Les services, volumes, réseaux et variables d’environnement conservent la même syntaxe entre les versions du format Compose. Un seul fichier centralise ainsi l’intégralité de votre architecture multi-conteneurs.
Sa structure est organisée autour de plusieurs clés de premier niveau :
- services : définit chaque conteneur à créer, avec son image ou son build, ses ports, ses variables, ses volumes et ses dépendances.
- networks : déclare les réseaux Docker qui permettent aux services de communiquer entre eux de façon isolée.
- volumes : déclare les volumes nommés utilisés pour persister les données en dehors des conteneurs.
- secrets : déclare les secrets montés en lecture seule dans les conteneurs, sans les exposer dans les variables d’environnement.
- configs : permet d’injecter des fichiers de configuration dans les services sans les intégrer à l’image.
Comment organiser la structure et la version du fichier ?
Avec Docker Compose V2, le champ version en tête de fichier est désormais déprécié et doit être retiré. Docker Compose V2 applique automatiquement le schéma le plus récent pour valider votre fichier, ce qui rend la clé version inutile. Si vous conservez cette clé, Compose affiche un avertissement de type WARN[0000] l'attribut "version" est obsolète. La bonne pratique consiste donc à commencer directement par la clé services:, sans aucune déclaration de version. La solution la plus propre est de supprimer complètement le champ version de vos fichiers Compose et de standardiser l’usage du plugin docker compose.
L’indentation YAML est strictement basée sur des espaces (jamais des tabulations) : chaque niveau hiérarchique ajoute deux espaces. Une erreur d’indentation peut empêcher Compose d’interpréter correctement votre fichier. Pour valider votre configuration avant de la déployer, utilisez la commande docker compose config : elle résout les variables d’environnement, fusionne les éventuels fichiers d’override et affiche le fichier résultant normalisé. C’est le premier réflexe à avoir en cas de comportement inattendu.
Services : image ou build ?
Au sein de la clé services, chaque service peut soit utiliser une image pré-construite via la directive image, soit construire sa propre image à partir d’un Dockerfile via la directive build. Ces deux approches répondent à des besoins distincts. La directive build accepte un context (le répertoire contenant le Dockerfile) et un target pour les builds multi-étapes. En développement, build permet de relancer docker compose up --build après chaque modification du code pour obtenir une image actualisée. En production, l’usage d’une image pré-construite depuis un registre garantit la reproductibilité et la rapidité du déploiement.
| Critère | image | build |
|---|---|---|
| Source | Registre Docker (Hub, privé) | Dockerfile local |
| Cas d’usage principal | Services tiers (BDD, cache, proxy) | Code applicatif personnalisé |
| Reproductibilité | Excellente (tag fixé) | Dépend du Dockerfile et du contexte |
| Vitesse de démarrage | Rapide (pull ou cache local) | Plus lente (compilation à chaque build) |
| Paramètres avancés | image: monapp:1.2.3 | context, dockerfile, target, args, cache_from |
| Usage recommandé | Staging et production | Développement local |
Comment exposer les ports et configurer les réseaux ?
La directive ports permet de mapper un port de l’hôte vers un port du conteneur, selon la syntaxe "PORT_HOTE:PORT_CONTENEUR". Par exemple, "8080:80" rend le port 80 du conteneur accessible sur le port 8080 de votre machine. Il est conseillé de n’exposer les ports à l’hôte que pour les services qui doivent être accessibles depuis l’extérieur. Une base de données ou un service de cache interne n’a pas besoin d’exposer ses ports : les autres services du même réseau Compose y accèdent déjà par leur nom de service.
Docker Compose crée les services selon un ordre de dépendance. Tous les services appartenant au même fichier Compose partagent automatiquement un réseau par défaut. Ce réseau est nommé <dossier>_default et permet à chaque service d’être joignable par son nom de service, grâce à la résolution DNS intégrée de Docker. Pour isoler certains services (par exemple, séparer le frontend du backend), vous pouvez déclarer des réseaux nommés personnalisés et y rattacher uniquement les services concernés. Les alias réseau permettent de référencer un service sous plusieurs noms au sein d’un même réseau.
Volumes : bind ou named ?
Docker propose deux mécanismes principaux pour faire persister les données d’un conteneur : les volumes nommés (gérés par Docker) et les montages de type bind (liés au système de fichiers de l’hôte). Le choix entre les deux dépend du contexte d’utilisation.
| Critère | Volume nommé (named volume) | Montage bind (bind mount) |
|---|---|---|
| Gestion | Par Docker (indépendant du chemin hôte) | Chemin absolu sur l’hôte |
| Persistance | Survit à la suppression du conteneur | Liée à l’existence du dossier hôte |
| Performances | Optimisées sur Linux et macOS | Peut être lent sur macOS/Windows |
| Sauvegarde | Via docker volume ou outils tiers | Sauvegarde directe du dossier hôte |
| Droits (uid/gid) | Configurable via driver_opts ou entrypoint | Hérite des droits du dossier hôte |
| Usage recommandé | Bases de données, données de production | Code source en développement |
En pratique, une stack applicative combine souvent les deux types : un volume nommé pour les données de la base de données (afin qu’elles ne soient pas perdues lors d’un docker compose down), et un montage bind pour le code source de l’application (pour que les modifications soient répercutées instantanément sans reconstruire l’image). Notez que docker compose down ne supprime pas les volumes nommés par défaut : il faut ajouter l’option -v pour les supprimer explicitement.
Comment gérer les variables d’environnement (.env, substitution, priorité) ?
Docker Compose V2 propose cinq mécanismes distincts pour les variables d’environnement, et ils ne produisent pas tous le même résultat. Les directives environment: et env_file: injectent les valeurs dans le conteneur en cours d’exécution, tandis que le fichier .env auto-chargé et le flag --env-file n’alimentent que la substitution ${VAR} à l’intérieur du fichier Compose lui-même, sans jamais atteindre le conteneur directement. Voici l’ordre de résolution complet, du plus prioritaire au moins prioritaire :
- Ligne de commande (
docker compose run -e VAR=valeur) : priorité maximale, écrase toutes les autres sources. - Variables du shell hôte interpolées dans
environment:ouenv_file:: valeur issue du shell ou d’un fichier d’environnement (fichier.envpar défaut ou via le flag--env-file). - Attribut
environment:dans le fichier Compose : valeur explicite définie directement dans le YAML. - Attribut
env_file:dans le fichier Compose : les valeurs définies viaenvironment:ont priorité sur celles chargées parenv_file:. - Directive
ENVde l’image Docker : valeur par défaut gravée dans le Dockerfile, utilisée uniquement si aucune autre source ne définit la variable.
Docker Compose charge automatiquement un fichier nommé .env situé dans le même répertoire que votre docker-compose.yml. Ce fichier sert à alimenter les substitutions ${...} dans le YAML et à centraliser les valeurs qui varient selon l’environnement (identifiants de BDD, ports, version d’image). Le fichier .env peut contenir des informations sensibles comme des clés d’API ou des mots de passe : il est impératif de ne jamais le committer dans votre dépôt Git. Ajoutez-le systématiquement à votre .gitignore. Pour changer d’environnement (staging, production), utilisez docker compose --env-file envs/staging.env up sans modifier aucun fichier.
Comment gérer les secrets en toute sécurité ?
Les variables d’environnement sont pratiques, mais elles présentent une limite importante en production : un docker inspect sur n’importe quel conteneur en cours d’exécution révèle le tableau Env complet, ce qui inclut tout ce qui a été passé via environment: ou env_file:. Pour une configuration non sensible, cela est acceptable, mais pour des mots de passe de bases de données, des clés d’API et des jetons en production, c’est un problème. Docker Compose propose un mécanisme de secrets pour répondre à ce besoin.
Avec les secrets Compose, le contenu sensible est monté sous forme de fichier dans le répertoire /run/secrets/<nom> à l’intérieur du conteneur, plutôt que d’être exposé comme variable d’environnement. Votre application lit le secret depuis ce fichier au moment de l’exécution. Ce mécanisme est nativement supporté par Docker Compose en mode autonome (standalone), à condition de référencer un fichier local comme source du secret. En production sur Docker Swarm ou Kubernetes, les secrets bénéficient d’un stockage chiffré et d’une distribution sécurisée entre les nœuds du cluster. Pour les environnements de développement local, la différence est faible, mais en production avec Docker Swarm ou Kubernetes, les secrets sont l’outil adapté pour tout ce qui est sensible.
Dépendances : depends_on et healthcheck, dans quel ordre démarrer ?
Par défaut, Compose n’attend pas qu’un conteneur soit « prêt », seulement qu’il soit en cours d’exécution. Cela peut poser problème si, par exemple, un système de base de données relationnelle doit initialiser ses propres processus avant d’être capable de traiter des connexions entrantes. Un depends_on simple garantit uniquement l’ordre de démarrage des processus, pas la disponibilité fonctionnelle du service. Un service WordPress qui tente de se connecter à MySQL pendant son initialisation échouera avec une erreur de connexion, même si MySQL a bien démarré avant lui.
La combinaison de depends_on avec condition: service_healthy est la solution pour imposer un ordre de démarrage basé sur la disponibilité réelle du service. La condition service_healthy attend qu’un healthcheck soit positif avant de démarrer le service dépendant. La condition service_completed_successfully attend qu’un conteneur se soit terminé avec succès, ce qui est utile pour les tâches de migration. Le bloc healthcheck configure la commande de vérification et ses paramètres : interval (fréquence des vérifications), timeout (durée maximale par vérification), retries (nombre d’échecs consécutifs avant de marquer le service comme non sain) et start_period (délai de grâce au démarrage pendant lequel les échecs ne comptent pas).
Pour les services HTTP, remplacez la commande pg_isready par un appel curl -f http://localhost:8080/health. Assurez-vous que l’image contient bien l’outil utilisé dans la commande de test : les images Alpine ne l’incluent pas par défaut. Les scripts externes de type wait-for-it ou dockerize restent une option pour les cas complexes, mais les healthchecks natifs sont l’approche moderne recommandée : ils sont intégrés à Docker, ne nécessitent pas de scripts supplémentaires et s’intègrent mieux avec les outils d’orchestration.
Quelles policies de redémarrage et limites de ressources définir ?
Les quatre politiques de redémarrage disponibles répondent à des cas d’usage différents :
no(défaut) : le conteneur ne redémarre jamais automatiquement. Convient aux tâches ponctuelles et aux environnements de test.always: redémarre quoi qu’il arrive, même après un arrêt manuel ou un redémarrage du serveur hôte. Adapté aux services de production critiques.unless-stopped: redémarre automatiquement sauf si vous avez explicitement arrêté le conteneur avecdocker compose stop. Le compromis le plus courant pour les services longue durée.on-failure: redémarre uniquement en cas de code de sortie non nul (crash applicatif). Idéal pour les workers et les jobs qui ne doivent pas redémarrer sur un arrêt propre.
Pour limiter les ressources consommées par un service, la Compose Specification utilise la clé deploy.resources. deploy.resources.limits.cpus configure le nombre maximum de cœurs CPU disponibles pour le conteneur, et deploy.resources.limits.memory définit la quantité maximale de mémoire allouée, exprimée sous forme de chaîne de caractères (par exemple 512M ou 2G). La clé reservations définit les ressources garanties (valeurs plancher), tandis que limits fixe le plafond. Avec Docker Swarm, la section deploy est native. En mode standalone (sans Swarm), Docker Compose applique également ces limites depuis la Compose Specification V2.
Profils, multi-fichiers et environnements : comment s’y prendre ?
Les profils permettent de définir des services optionnels qui ne démarrent que lorsqu’on les demande explicitement. Un service associé à un profil ne se lance pas avec un simple docker compose up : il faut activer le profil via l’option --profile nom_du_profil. Cette fonctionnalité est particulièrement utile pour les outils d’administration (pgAdmin, phpMyAdmin), les services de debug (hot-reload, linter) ou les mocks de test qui ne doivent pas encombrer l’environnement de production.
Pour gérer plusieurs environnements (développement, staging, production), Docker Compose supporte la fusion de plusieurs fichiers YAML. Le fichier docker-compose.override.yml est chargé automatiquement en complément du fichier de base, sans aucun flag supplémentaire : c’est l’emplacement idéal pour les surcharges de développement (montages bind, ports de debug, logs verbeux). Pour les autres environnements, utilisez l’option -f pour spécifier explicitement les fichiers à fusionner.
| Fichier | Rôle | Chargement |
|---|---|---|
compose.yml | Configuration de base commune (images, réseaux, volumes) | Automatique |
compose.override.yml | Surcharges de développement (bind mounts, ports debug) | Automatique (dev uniquement) |
compose.staging.yml | Configuration staging (logs, ressources limitées) | -f compose.yml -f compose.staging.yml |
compose.prod.yml | Configuration production (images taggées, limites strictes, secrets) | -f compose.yml -f compose.prod.yml |
Déploiement et gestion des applications

Une fois votre fichier docker-compose.yml rédigé, la mise en production ou le déploiement sur un environnement cible se résume à quelques commandes standardisées. Docker Compose orchestre l’ensemble du cycle de vie de votre application : création, démarrage, arrêt, mise à jour et suppression des conteneurs. Maîtriser ces opérations concrètes vous permet de travailler de façon fiable, que vous soyez en développement local ou sur un serveur dédié.
- Déploiement initial : construire ou récupérer les images, puis démarrer l’ensemble de la stack en arrière-plan.
- Gestion quotidienne : accéder aux logs, exécuter des commandes ponctuelles, ouvrir un shell dans un conteneur.
- Mises à jour : tirer les nouvelles versions d’images, recréer les conteneurs concernés et savoir revenir en arrière si besoin.
- Scaling : multiplier les réplicas d’un service sur un hôte unique, en ayant conscience des limites de l’outil.
- Dépannage : identifier rapidement les erreurs courantes grâce à une checklist méthodique.
Comment effectuer le déploiement initial ?
Le déploiement initial suit toujours la même séquence logique : préparer les images, démarrer les services, puis vérifier que tout fonctionne correctement. Voici les étapes à suivre dans l’ordre :
- Récupérer ou construire les images : si vos services utilisent des images publiques, tirez-les avec
docker compose pull. Si vous avez unDockerfilepersonnalisé, construisez les images avecdocker compose build. Combiner les deux est possible selon la configuration de votre stack. - Démarrer la stack en arrière-plan : lancez
docker compose up -ddepuis le répertoire contenant votre fichier Compose. L’option-d(detached) libère votre terminal pendant que les conteneurs tournent en tâche de fond. Vous pouvez combiner build et démarrage en une seule commande :docker compose up -d --build. - Vérifier l’état des conteneurs : exécutez
docker compose pspour confirmer que tous les services sont bien à l’étatrunning. Un service en statutexitedourestartingsignale immédiatement un problème. - Consulter les logs de démarrage : utilisez
docker compose logs --follow(ou-f) pour surveiller les sorties en temps réel et détecter toute erreur d’initialisation, de connexion à la base de données ou de configuration manquante. - Valider l’application : accédez à l’URL ou au port exposé pour confirmer que l’application répond correctement. Si vous avez défini des healthchecks, attendez qu’ils passent au vert avant de considérer le déploiement réussi.
Un point important sur l’idempotence : docker compose up -d est conçu pour être rejoué sans risque. Si les conteneurs existent déjà et sont conformes à la configuration, Compose ne les recrée pas. Il ne redémarre que les services dont la configuration a changé. Vous pouvez donc exécuter cette commande autant de fois que nécessaire sans craindre de perturber une stack déjà opérationnelle.
Quelles commandes Compose utiliser au quotidien ?
La CLI Docker Compose propose un ensemble de commandes couvrant l’intégralité du cycle de vie d’une application. Le tableau suivant récapitule celles que vous utiliserez le plus souvent, toutes à exécuter depuis le dossier contenant votre fichier Compose :
| Commande | Rôle | Usage typique |
|---|---|---|
docker compose up -d | Crée et démarre tous les services en arrière-plan | Premier démarrage ou redéploiement |
docker compose down | Arrête et supprime les conteneurs et les réseaux créés | Nettoyage complet de la stack (ajouter -v pour supprimer aussi les volumes) |
docker compose start | Démarre des conteneurs déjà créés mais arrêtés | Reprendre une stack existante sans la recréer |
docker compose stop | Arrête les conteneurs sans les supprimer | Pause temporaire, conservation des données |
docker compose restart | Redémarre un ou tous les services | Appliquer un changement de configuration sans recréer |
docker compose logs -f | Affiche et suit les logs en temps réel | Débogage, surveillance des erreurs au démarrage |
docker compose exec | Exécute une commande dans un conteneur en cours d’exécution | Ouvrir un shell : docker compose exec app bash |
docker compose run | Lance un conteneur ponctuel (one-off) pour un service | Migrations, scripts d’initialisation, tests |
docker compose build | Construit ou reconstruit les images définies avec build: | Après modification d’un Dockerfile |
docker compose pull | Tire les dernières versions des images depuis le registre | Avant une mise à jour |
docker compose push | Pousse les images construites vers un registre | Intégration CI/CD, partage d’images |
docker compose ps | Liste l’état de tous les services | Vérification rapide de la santé de la stack |
docker compose config | Affiche la configuration finale résolue (avec variables) | Valider le fichier Compose avant déploiement |
Comment gérer les conteneurs au quotidien ?
Au-delà du simple démarrage et arrêt, la gestion quotidienne d’une stack Docker Compose implique d’interagir directement avec les conteneurs en cours d’exécution : inspecter leur état interne, exécuter des tâches ponctuelles ou transférer des fichiers. Ces opérations s’effectuent sans jamais avoir besoin de reconstruire l’ensemble de la stack.
- Cycle de vie granulaire : vous pouvez cibler un service spécifique dans vos commandes. Par exemple,
docker compose restart apine redémarre que le serviceapi, sans toucher à la base de données ou au cache. - Exécution ponctuelle (one-off) : la commande
docker compose run --rm app php artisan migratecrée un conteneur temporaire basé sur le serviceapp, exécute la migration, puis le supprime automatiquement grâce à--rm. C’est la méthode recommandée pour les scripts d’initialisation ou de maintenance. - Accès shell interactif : pour inspecter l’intérieur d’un conteneur actif, utilisez
docker compose exec nom_du_service bash(oushsi bash n’est pas disponible). C’est utile pour déboguer la configuration, vérifier les variables d’environnement injectées ou tester la connectivité réseau entre services. - Copie de fichiers : la commande
docker compose cp(oudocker cpavec l’identifiant du conteneur) permet de transférer des fichiers entre l’hôte et un conteneur en cours d’exécution, par exemple pour récupérer un fichier de log ou injecter un fichier de configuration temporaire. - Inspection des ressources :
docker compose topliste les processus actifs dans chaque conteneur, etdocker statsaffiche la consommation CPU et mémoire en temps réel pour surveiller les services gourmands.
Logs et monitoring : que surveiller ?
- Logs agrégés de la stack :
docker compose logs -faffiche les sorties de tous les services en continu, avec le nom du service en préfixe pour identifier la source. Filtrez par service avecdocker compose logs -f nom_service. - Nombre de lignes limitées : pour ne pas noyer la console, utilisez
docker compose logs --tail=100 nom_servicepour n’afficher que les 100 dernières lignes. - État des healthchecks :
docker compose psindique si un service esthealthy,unhealthyoustarting. Un serviceunhealthyqui reste en service actif signale une dégradation silencieuse. - Consommation des ressources :
docker statsfournit en temps réel l’usage CPU, mémoire, réseau et disque de chaque conteneur. Particulièrement utile pour détecter une fuite mémoire ou un service en runaway. - Intégrations possibles : pour un monitoring plus avancé, des outils comme Prometheus avec cAdvisor collectent les métriques des conteneurs Docker, tandis que Loki (avec Grafana) centralise les logs. Ces intégrations s’ajoutent facilement comme services supplémentaires dans votre fichier Compose.
En pratique, le premier réflexe face à tout incident doit toujours être docker compose logs. La grande majorité des problèmes de démarrage, de connexion entre services ou de configuration se diagnostiquent directement dans les logs, bien avant de recourir à des outils externes.
Mise à jour et rollback : quelle stratégie ?
Mettre à jour une stack Docker Compose sans interruption prolongée nécessite une procédure rigoureuse. Voici les étapes recommandées :
- Tirer les nouvelles images : exécutez
docker compose pullpour récupérer les dernières versions de toutes les images référencées. Pour une image personnalisée, lancezdocker compose build --no-cachepour forcer une reconstruction complète sans utiliser le cache. - Appliquer les migrations de base de données : avant de recréer les conteneurs applicatifs, exécutez les éventuels scripts de migration avec
docker compose run --rm app python manage.py migrate(ou l’équivalent de votre framework). Assurez-vous que le schéma cible est compatible avec l’ancienne version de l’application, surtout si un rollback peut être nécessaire. - Recréer les conteneurs : relancez
docker compose up -d --force-recreatepour forcer Compose à recréer les conteneurs avec les nouvelles images, même si la configuration YAML n’a pas changé. Compose arrête puis redémarre chaque service concerné. - Vérifier l’état post-déploiement : contrôlez immédiatement avec
docker compose psetdocker compose logs -fque tous les services sont opérationnels après la mise à jour. - Rollback si nécessaire : taguez systématiquement vos images avec un numéro de version explicite (ex :
monapp:1.4.2) plutôt que d’utiliser uniquementlatest. En cas de problème, il suffit de modifier le tag dans le fichier Compose pour revenir à la version précédente, puis de relancerdocker compose up -d --force-recreate.
La différence entre une mise à jour réussie et un incident en production tient souvent à la gestion des tags d’images et à la compatibilité de schéma. Utiliser latest en production est risqué : vous ne contrôlez plus quelle version exacte tourne sur votre serveur. En revanche, avec des tags versionnés, le rollback est immédiat et déterministe. Pensez également que certaines migrations de base de données sont irréversibles : dans ce cas, prévoir un backup avant toute mise à jour est indispensable.
Scaling et réplication : jusqu’où aller ?
Docker Compose permet de lancer plusieurs réplicas d’un même service grâce à l’option --scale. Par exemple, docker compose up -d --scale worker=4 crée quatre conteneurs identiques pour le service worker, ce qui permet de distribuer la charge de traitement sur plusieurs processus tournant en parallèle sur la même machine. Vous pouvez aussi définir le nombre de réplicas directement dans le fichier Compose via la clé deploy.replicas. Cette approche est particulièrement utile pour les workers de traitement asynchrone ou les services sans état (stateless).
Cependant, le scaling avec Compose est limité à un hôte unique : tous les réplicas tournent sur le même serveur physique ou virtuel. Cela signifie qu’ils partagent les mêmes ressources CPU et mémoire, et que si la machine tombe, toute la stack s’arrête avec elle. De plus, les services avec des ports exposés sur l’hôte ne peuvent pas être scalés directement sans passer par un load balancer intermédiaire, car deux conteneurs ne peuvent pas écouter sur le même port hôte simultanément. En environnement de production avec des besoins de haute disponibilité, de distribution multi-serveurs ou de basculement automatique, Docker Compose atteint ses limites. C’est le signal pour envisager la migration vers Docker Swarm (pour une transition simple) ou Kubernetes (pour une orchestration complète).
Dépannage : comment résoudre les erreurs courantes ?
Face à un problème sur une stack Compose, une checklist méthodique permet de cibler rapidement la cause. Voici les vérifications à effectuer dans l’ordre :
- Port déjà occupé : le message
Bind for 0.0.0.0:80 failed: port is already allocatedindique qu’un autre processus utilise le port souhaité. Identifiez-le avecsudo lsof -i :80(Linux/macOS) ounetstat -ano | findstr :80(Windows), puis arrêtez le processus en conflit ou changez le port dans votre fichier Compose. - Problème de permissions sur les volumes : si un conteneur échoue en signalant un accès refusé sur un répertoire monté en bind mount, vérifiez que l’utilisateur dans le conteneur (souvent
www-data,nodeou un UID numérique) a bien les droits en lecture/écriture sur le dossier hôte correspondant. Ajustez avecchmodouchowncôté hôte, ou définissez unuser:explicite dans le service Compose. - Résolution DNS entre services échouée : si un service ne parvient pas à joindre un autre par son nom (ex :
mysqlnon résolu depuiswordpress), vérifiez que les deux services sont bien sur le même réseau Compose. Un service sans réseau explicite rejoint le réseaudefault, mais si vous avez déclaré des réseaux personnalisés, chaque service doit y être rattaché explicitement. - Service dépendant non prêt (depends_on insuffisant) :
depends_ongarantit uniquement l’ordre de démarrage des conteneurs, pas que le service soit opérationnel. Si votre application tente de se connecter à la base de données trop tôt, ajoutez un healthcheck sur le service base de données et utilisezcondition: service_healthydansdepends_onpour attendre que MySQL ou PostgreSQL soit réellement prêt à accepter des connexions. - Variables d’environnement non injectées : si votre application se plaint d’une variable manquante, exécutez
docker compose configpour voir la configuration résolue avec toutes les substitutions de variables, et vérifiez que le fichier.envest bien présent dans le même dossier que le fichier Compose. - Image introuvable ou obsolète : une erreur
pull access deniedoumanifest unknownsignale un tag d’image inexistant ou une authentification manquante au registre. Vérifiez le nom et le tag de l’image, et connectez-vous avecdocker loginsi le registre est privé.
Prenons un cas concret : votre service applicatif affiche Error: connect ECONNREFUSED 127.0.0.1:5432 au démarrage. L’erreur indique que l’application tente de joindre PostgreSQL sur localhost plutôt que sur le nom du service (db par exemple). La cause est une variable DATABASE_HOST mal configurée ou oubliée. La correction consiste à vérifier dans docker compose config que la variable pointe bien vers le nom du service Compose, et non vers 127.0.0.1, qui n’a aucun sens dans un réseau de conteneurs où chaque service a sa propre interface réseau.
Bonnes pratiques Docker Compose

Maîtriser Docker Compose ne se résume pas à écrire un fichier YAML qui fonctionne. Cela implique d’adopter des habitudes reproductibles sur l’organisation du projet, la sécurité, la gestion des données, les performances et l’intégration dans les pipelines CI/CD. Voici une check-list des points à couvrir avant de passer en production ou de partager un projet en équipe :
- Nommer le fichier principal
compose.yamlet structurer le projet avec des fichiers d’override par environnement. - Factoriser les blocs répétés grâce aux ancres YAML et aux champs d’extension
x-. - Ne jamais placer de secrets en clair dans le YAML versionné ; utiliser un fichier
.envou les secrets Docker. - Épingler les images à une version précise plutôt qu’à
:latest. - Définir des volumes nommés pour toutes les données persistantes et planifier des sauvegardes automatisées.
- Fixer des limites CPU et mémoire sur chaque service pour éviter les effets de voisinage bruyant (noisy neighbor).
- Intégrer Compose dans la pipeline CI/CD pour les tests d’intégration et les environnements éphémères.
- Utiliser exclusivement Compose V2 (
docker composeavec un espace) et omettre le champversion:devenu obsolète.
Comment organiser le projet et factoriser le YAML ?
Pour gérer plusieurs environnements sans dupliquer toute la configuration, adoptez une structure à trois fichiers :
compose.yaml: configuration de base commune à tous les environnements.compose.override.yaml: surcharge développement, chargée automatiquement par Compose ; elle peut inclure des montages de bind, des ports supplémentaires, du hot-reload.compose.prod.yaml: surcharge production, à passer explicitement avec-f, avec les limites de ressources, les secrets et les réseaux dédiés.
Exemple concret : factoriser la configuration de logging et les limites de ressources partagées par plusieurs services :
Les ancres et alias YAML permettent de définir une configuration une seule fois et de la réutiliser autant de fois que nécessaire dans le fichier Compose. Cela réduit la duplication, prévient les erreurs de copier-coller et facilite les mises à jour lorsque des paramètres communs doivent changer. Utilisez toujours docker compose config après avoir introduit des ancres : cette commande affiche le YAML entièrement résolu avec toutes les ancres développées et tous les alias remplacés, vous montrant exactement ce que Docker Compose va réellement utiliser.
Quelles bonnes pratiques de sécurité appliquer ?
- Ne jamais mettre de secrets en clair dans le fichier Compose. Aucun mot de passe, clé API ou token ne doit figurer directement dans
compose.yaml. - Externaliser les variables sensibles dans un fichier
.envet l’ajouter au.gitignore. Fournir un.env.exampleversionné comme modèle. - Utiliser les secrets Docker pour la production. Pour les credentials et les clés API, les secrets Docker sont plus sûrs. En mode non-Swarm, les secrets Compose sont montés sous forme de fichiers à l’intérieur du conteneur, à l’emplacement
/run/secrets/<nom-du-secret>. L’application lit le fichier au démarrage plutôt qu’une variable d’environnement. - Épingler les images à une version précise :
postgres:16.2-alpine3.19plutôt quepostgres:latest. L’épinglage assure la reproductibilité, cruciale pour les pipelines CI/CD et les audits de sécurité. - Privilégier les images officielles ou minimales (variantes
alpine,slim) pour réduire la surface d’attaque. - Exécuter les processus en tant qu’utilisateur non-root dans le Dockerfile (
USER appuser) afin de limiter les dommages en cas de compromission. - Ne pas exposer les ports inutilement. Seuls les services accessibles de l’extérieur (serveur web, reverse proxy) doivent avoir une section
ports. Les bases de données et les caches restent accessibles uniquement via le réseau interne Compose. - Monter le système de fichiers racine en lecture seule (
read_only: true) et n’autoriser l’écriture que sur les chemins explicitement déclarés entmpfs.
Les variables d’environnement sont le moyen le plus simple de passer de la configuration, mais elles sont visibles dans docker inspect, dans les listings de processus (/proc/<pid>/environ) et peuvent être divulguées dans les logs. Un secret qui se retrouve dans l’historique Git ou dans les logs d’un pipeline est extrêmement difficile à invalider rétroactivement : la rotation des credentials, la révocation des tokens et l’audit des accès représentent un coût bien supérieur à l’effort initial de gestion correcte des secrets.
Données et sauvegardes : quelle stratégie ?
Les volumes Docker stockent vos bases de données, vos fichiers uploadés et l’état de vos applications. Les perdre signifie perdre des données. Contrairement aux images de conteneurs qui peuvent être reconstruites, les données de volumes sont uniques et irremplaçables. Une stratégie de sauvegarde solide est non négociable pour les charges de travail en production.
- Utiliser des volumes nommés pour toutes les données persistantes. Les volumes nommés sont considérés comme la bonne pratique pour la gestion du stockage dans Docker. Ils sont persistants, partageables et faciles à gérer sur différents hôtes. Ils offrent également une séparation claire entre les données et les conteneurs, facilitant la gestion et la migration indépendante des données.
- Sauvegarder avec les outils natifs de la base de données. Si vous avez besoin de sauvegarder une base de données dans un conteneur Docker, vous ne devez pas sauvegarder le conteneur lui-même ni le volume où sont stockées les données. Utilisez plutôt la méthode recommandée par l’éditeur de la base de données. Exemples :
pg_dumppour PostgreSQL,mysqldumppour MySQL. - Automatiser les sauvegardes et les tester régulièrement. La bonne pratique consiste à automatiser les sauvegardes avec des cron jobs ou l’outil
docker-volume-backup, et à tester régulièrement les procédures de restauration. Une sauvegarde non testée est une sauvegarde dont on ne peut pas garantir l’intégrité. - Pour la restauration d’un volume, arrêtez d’abord les conteneurs qui l’utilisent, puis montez le volume dans un conteneur temporaire pour y extraire l’archive :
docker run --rm -v mon_volume:/target -v $(pwd)/backups:/backup:ro alpine tar xzf /backup/sauvegarde.tar.gz -C /target. Relancez ensuite les services avecdocker compose up -d. - Gérer les migrations de schéma avant le démarrage de l’application. Ajoutez un service de migration one-shot (par exemple
alembic upgrade headourails db:migrate) avecrestart: "no"et configurez l’application principale avecdepends_on: migration: condition: service_completed_successfullypour garantir que le schéma est à jour avant tout démarrage.
Performances : quelles limites et optimisations ?
- Définir des limites CPU et mémoire sur chaque service. Les conteneurs sans limites de ressources peuvent consommer toutes les ressources disponibles de l’hôte, provoquant des défaillances en cascade. Un seul conteneur incontrôlé peut affamer les autres services, faire planter l’hôte ou déclencher l’OOM killer qui met fin aux processus critiques. Utilisez la syntaxe
deploy.resources.limitsdans la Compose Specification. - Préférer les volumes nommés aux bind mounts pour les données de production. Les volumes nommés sont bien plus performants que les bind mounts pour le stockage de données persistantes. Pour les données éphémères, les montages tmpfs peuvent améliorer les performances d’E/S en stockant les données en mémoire.
- Utiliser
tmpfspour les données temporaires à haute fréquence d’écriture. La configurationtmpfsde Docker Compose monte un système de fichiers en RAM à l’intérieur du conteneur, offrant un stockage éphémère ultra-rapide qui disparaît à l’arrêt du conteneur. Exemples typiques : sessions PHP, fichiers de cache, répertoires/tmpet/run. - Configurer le driver de logging
json-fileavec rotation. Sans limite, les fichiers de logs peuvent saturer le disque de l’hôte. Ajoutez systématiquementmax-size: "10m"etmax-file: "3"dans la sectionloggingde chaque service. - Utiliser des bind mounts uniquement en développement pour le hot-reload du code source, jamais en production où la couche Union FS du conteneur ou un volume nommé offrent de meilleures garanties.
Le but est de donner à chaque conteneur suffisamment de ressources pour son activité normale et ses pics, tout en empêchant un processus défaillant de faire tomber tout le reste de la machine. En pratique, commencez sans limites strictes dans un environnement de test en relevant la consommation au repos, en charge normale et en pic ; puis définissez la limite mémoire au-dessus du pic observé, en conservant une marge pour le garbage collection, la croissance du cache et les courtes rafales. Voici un exemple de configuration combinant limites CPU/mémoire, tmpfs et logging :
CI/CD et environnements : comment intégrer Compose ?
Docker transforme les pipelines CI/CD en fournissant des environnements cohérents et reproductibles du développement à la production. Construire des applications conteneurisées via des pipelines automatisés élimine le problème classique du « ça marche sur ma machine » et accélère les cycles de déploiement. Cas concret : dans un pipeline GitHub Actions ou GitLab CI, on utilise un fichier dédié compose.ci.yaml pour démarrer la stack complète (application, base de données, service de cache), exécuter les tests d’intégration dans un conteneur éphémère, puis tout démanteler proprement.
L’option --wait attend que tous les healthchecks soient positifs avant de passer à l’étape suivante. L’option -p (project name) permet d’isoler plusieurs builds parallèles sur le même runner sans conflit de noms de conteneurs.
- Créer un fichier
compose.ci.yamldédié aux tests : images légères, pas de volumes bind, services éphémères sans politique de redémarrage (restart: "no"). - Utiliser
--waitet les healthchecks pour s’assurer que les services dépendants (base de données, broker de messages) sont réellement prêts avant de lancer les tests. - Isoler chaque build par un project name unique (
-p ci-test-$BUILD_ID) pour permettre l’exécution parallèle sur un même agent. - Gérer les matrices d’environnements (dev, staging, prod) avec des fichiers d’override ciblés (
-f compose.yaml -f compose.staging.yaml) plutôt qu’en dupliquant l’intégralité du fichier de base. - Toujours nettoyer après les tests avec
docker compose down -v --remove-orphansdans un bloctrapou équivalent pour libérer les volumes et éviter l’accumulation de ressources orphelines sur le runner. - Construire l’image une seule fois, l’exécuter dans les tests unitaires et d’intégration, puis promouvoir cette même image à travers les stages QA et production pour garantir la parité des environnements.
Compatibilité et versions : à quoi faire attention ?
Compose V2, annoncé en 2020, est écrit en Go et s’invoque avec docker compose (avec un espace). Contrairement à V1, Compose V2 ignore le champ version: de premier niveau dans le fichier compose.yaml et s’appuie entièrement sur la Compose Specification pour interpréter le fichier.
| Aspect | Compose V1 (obsolète) | Compose V2 / Compose Specification |
|---|---|---|
| Commande CLI | docker-compose (avec tiret) |
docker compose (avec espace) |
| Langage | Python (binaire standalone) | Go (plugin Docker CLI) |
Champ version: |
Obligatoire (2.x, 3.x) | Obsolète, à omettre |
| Nom des conteneurs | projet_service_1 (tiret bas) |
projet-service-1 (tiret) |
| Support | Fin de vie juillet 2023 | Activement maintenu |
| Fonctionnalités clés | Basiques | Profils, service_completed_successfully, accès GPU, secrets |
| Nom de fichier recommandé | docker-compose.yml |
compose.yaml |
La bonne pratique actuelle est d’utiliser Docker Compose V2 exclusivement et d’omettre entièrement le champ version. Compose V1 utilisait une commande avec un tiret (docker-compose), tandis que V2 utilise un espace (docker compose). Certains scripts et pipelines CI se cassent lors du passage de l’un à l’autre. Si vous maintenez des scripts hérités, remplacez systématiquement docker-compose par docker compose et vérifiez les noms de conteneurs générés automatiquement (le tiret bas remplacé par un tiret peut casser des scripts qui référencent des conteneurs par leur nom). Compose V2 implémente la Compose Specification ouverte, maintenue indépendamment de Docker sur compose-spec.io. Cela signifie que le format est neutre vis-à-vis des fournisseurs : Podman Compose et d’autres runtimes peuvent consommer le même fichier.
Quelles sont les limites de Docker Compose ?

Docker Compose est un outil remarquable pour le développement local et les environnements de test : il simplifie la gestion de plusieurs conteneurs sur une seule machine, avec un fichier YAML et une commande unique. Si votre application tourne sur un seul serveur et que des interruptions de maintenance restent acceptables, Docker Compose est tout à fait suffisant. C’est précisément dans ce périmètre qu’il excelle.
En revanche, Docker Compose n’est pas un orchestrateur de production au sens plein du terme. Docker lui-même ne se préoccupe pas de distribuer les conteneurs sur plusieurs hôtes, de les redémarrer après une panne, ni d’équilibrer le trafic entre eux. Pour ces besoins, il faut se tourner vers un véritable orchestrateur multi-nœuds comme Docker Swarm ou Kubernetes, qui coordonnent les conteneurs sur un cluster de plusieurs serveurs.
Quand Compose atteint-il ses limites ?
Plusieurs situations concrètes révèlent les limites structurelles de Docker Compose en production :
- Panne du serveur : si le serveur hébergeant vos conteneurs tombe en panne, Compose ne dispose d’aucun mécanisme pour redémarrer automatiquement les services sur une autre machine. Vos applications s’arrêtent jusqu’à intervention manuelle.
- Mise à l’échelle multi-hôtes : dès que vous avez besoin de déploiements progressifs, d’auto-scaling, de vérifications d’état qui redémarrent les services défaillants, ou de la capacité à fonctionner sur plusieurs nœuds, Compose atteint ses limites.
- Haute disponibilité : Compose ne permet pas de répliquer vos services sur plusieurs serveurs physiques. Un seul point de défaillance suffit à interrompre l’ensemble de la stack.
- Auto-healing avancé : Kubernetes va plus loin que Compose en détectant les healthchecks défaillants, en retirant les pods affectés du load balancing avant de les redémarrer, et en redistribuant automatiquement les charges de travail en cas de défaillance d’un nœud. Compose ne propose pas ce niveau de résilience.
- Déploiement sans interruption (zero downtime) : les mises à jour applicatives avec Compose impliquent généralement un arrêt puis un redémarrage des conteneurs, sans possibilité native de rolling update sur plusieurs machines.
- Monitoring intégré : Compose ne dispose d’aucun mécanisme natif d’observabilité à l’échelle d’un cluster, contrairement à Kubernetes qui s’intègre nativement avec des outils de métriques et d’alerting.
En résumé, à mesure que votre système grandit, Compose devient plus difficile à mettre à l’échelle, à sécuriser et à gérer selon les environnements. Une architecture qui tourne parfaitement en développement peut devenir un risque opérationnel dès lors qu’elle est exposée à du trafic réel, à des pics de charge ou à des exigences de continuité de service.
Quelles alternatives pour aller plus loin ?
Deux orchestrateurs se distinguent pour prendre le relais de Docker Compose en production. Le tableau ci-dessous résume les principales différences pour vous aider à choisir :
| Critère | Docker Compose | Docker Swarm | Kubernetes (K8s) |
|---|---|---|---|
| Déploiement multi-hôtes | Non | Oui | Oui |
| Haute disponibilité | Non | Partielle | Native et avancée |
| Auto-scaling | Manuel, mono-machine | Manuel | Automatique (HPA/VPA) |
| Auto-healing | Basique (restart policy) | Oui | Avancé (liveness/readiness probes) |
| Courbe d’apprentissage | Faible | Faible | Élevée |
| Proximité avec Compose | Référence | Très proche (fichiers YAML quasi identiques) | Différent (API, CLI kubectl) |
| Usage recommandé | Dev, test, CI | Petite production, équipes réduites | Production à grande échelle |
Docker Swarm séduit par sa simplicité : si vous connaissez déjà Docker, la transition est quasi immédiate, avec des commandes CLI familières et des fichiers Docker Compose réutilisables. La faible barrière à l’entrée permet de commencer à orchestrer des conteneurs en production en quelques heures plutôt qu’en plusieurs jours. L’écosystème Swarm s’est cependant réduit significativement ces dernières années, de nombreux outils et fournisseurs cloud s’étant concentrés sur Kubernetes. Swarm reste techniquement solide, mais toute équipe qui envisage la production doit évaluer sa pérennité à long terme.
Kubernetes, en revanche, est complexe mais puissant et fournit des capacités de self-healing et d’auto-scaling directement intégrées. Il domine la production, avec 82 % des utilisateurs de conteneurs qui le font tourner en production. La migration depuis Compose vers Kubernetes n’est pas triviale : il faut réécrire les définitions de services en manifestes YAML spécifiques, gérer les Pods, Deployments, Services et PersistentVolumeClaims. Pour faciliter cette transition, deux outils sont particulièrement utiles :
- Compose Bridge (outil officiel Docker) : Compose Bridge convertit votre configuration Docker Compose en formats de déploiement spécifiques à une plateforme, comme les manifestes Kubernetes. Il vous aide à combler l’écart entre Compose et Kubernetes, en facilitant l’adoption de Kubernetes tout en conservant la simplicité de Compose.
- Kompose (outil open source, projet Kubernetes) : Kompose est un outil qui traduit les fichiers Docker Compose en manifestes Kubernetes. Il ne produit pas des manifestes parfaits pour la production, mais constitue un excellent point de départ.
La règle pratique à retenir est simple : utilisez Docker Compose en développement et en test. Dès que votre projet exige de la haute disponibilité, du scaling automatique ou un déploiement sans interruption en production, passez à Kubernetes (ou au minimum à Docker Swarm pour une première étape). De nombreuses équipes adoptent d’ailleurs une approche hybride : Compose en local et Kubernetes en production.
Conclusion
Docker Compose est un outil incontournable pour tout développeur travaillant avec des applications multi-conteneurs. Grâce à un simple fichier docker-compose.yml, il devient possible de définir, orchestrer et lancer l’ensemble de vos services en une seule commande, sans avoir à gérer chaque conteneur séparément. Que vous travailliez sur un environnement de développement local, un pipeline CI ou un environnement de test, Docker Compose simplifie considérablement la gestion de votre infrastructure applicative.
Voici les points essentiels à retenir avant de vous lancer :
- Un seul fichier YAML pour décrire toute votre architecture : services, réseaux et volumes.
- Trois concepts fondamentaux : les services (vos conteneurs), les réseaux (leur communication) et les volumes (la persistance des données).
- Deux commandes clés :
docker compose up -dpour démarrer l’ensemble de la stack,docker compose downpour tout arrêter proprement. - Sécurité : externalisez toujours vos secrets et mots de passe dans un fichier
.env, jamais en clair dans le fichier YAML versionné. - Robustesse : utilisez les healthchecks pour vous assurer que les services dépendants attendent que leurs dépendances soient réellement prêtes avant de démarrer.
- Limites à connaître : Docker Compose est conçu pour piloter une seule machine. Pour un déploiement en production nécessitant haute disponibilité ou scaling multi-serveurs, orientez-vous vers Kubernetes ou Docker Swarm.
Pour aller plus loin, consultez la documentation officielle Docker Compose, qui couvre l’ensemble des options du fichier Compose, les commandes CLI et les cas d’usage avancés. Vous pouvez également revenir aux sections pratiques de cet article pour l’installation, la structure du fichier docker-compose.yml et les commandes essentielles du quotidien.













