Introduction
La configuration d’un laboratoire local Docker Compose avec exemples pratiques aide les opérateurs à passer d’un problème observé à un résultat vérifié. Commencez par identifier les versions installées de Docker et de Compose, la topologie de déploiement, les prérequis et le composant exact inspecté. Un laboratoire local qui reproduit suffisamment la production pour reproduire les pannes est essentiel pour tester, déboguer et déployer en toute sécurité.
Cet article se concentre sur le laboratoire local Docker Compose pour les développeurs, les consultants DevOps et les équipes techniques de startups. Il relie la configuration de Docker Compose, les tests, les exemples et le développement aux commandes, aux sorties attendues, aux signaux de défaillance et aux décisions de reprise. L’objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d’impact, utiliser des variables fictives plutôt que des secrets, vérifier le résultat et documenter comment récupérer si l’état attendu n’est pas atteint.
Tous les exemples utilisent la syntaxe Docker Compose v2 (docker compose sans trait d’union). Si vous utilisez encore la commande v1 héritée (docker-compose), mettez à niveau vers un moteur Docker actuel ou ajustez les commandes en conséquence. Avant de commencer, confirmez les versions installées et que le démon Docker est en cours d’exécution.
Inventaire des versions et de l’environnement
Avant d’apporter une modification, enregistrez l’environnement exactement tel qu’il est. Cette section couvre ce qu’il faut vérifier, pourquoi c’est important et les commandes exactes à exécuter.
Ce qu’il faut enregistrer
- Version du moteur Docker :
docker --version - Version de Docker Compose :
docker compose version(v2) oudocker-compose --version(v1) - Noyau Linux et système d’exploitation :
uname -aetcat /etc/os-release - Utilisateur actuel et permissions Docker :
id,docker info(vérifiez les erreurs de permission) - Espace disque pour les images et les volumes :
df -h /var/lib/docker(ou votre répertoire racine Docker) - Paramètres de proxy ou de miroir pertinents pour le tirage des images
Exemple :
$ docker --version
Docker version 24.0.7, build afdd53b
$ docker compose version
Docker Compose version v2.21.0
$ uname -a
Linux devbox 6.1.0-17-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.69-1 (2023-12-30) x86_64 GNU/Linux
Si docker compose version renvoie « commande introuvable », installez le plugin Docker Compose (le binaire autonome est déprécié pour la plupart des distributions). Pour des instructions spécifiques au paquet, consultez la documentation officielle de Docker pour votre système d’exploitation.
Pourquoi la version est importante
Le format de fichier Compose est versionné, mais le Compose v2 moderne ignore la clé de niveau supérieur version: et utilise le schéma le plus récent. Cependant, des fonctionnalités comme init, develop ou include nécessitent des versions récentes de Compose. Par exemple, docker compose include a été ajouté dans la v2.20. Si vous partagez un laboratoire avec des coéquipiers, indiquez la version minimale de Compose prise en charge dans le README du projet.
Observation de l’état actuel (lecture seule)
Utilisez docker ps pour voir les conteneurs en cours d’exécution. La chaîne de format ci-dessous vous donne les noms, les états et les ports dans un tableau :
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
Pour un projet Compose spécifique, docker compose ps affiche les conteneurs appartenant à ce projet (le nom du répertoire par défaut). Pour voir tous les conteneurs, y compris ceux arrêtés, ajoutez -a.
Exemple de sortie :
NAMES STATUS PORTS
app-web-1 Up 2 hours 0.0.0.0:8080->80/tcp
app-db-1 Up 2 hours (healthy) 0.0.0.0:5432->5432/tcp
Si un conteneur est en mauvaise santé, docker inspect --format '{{json .State.Health}}' app-db-1 affiche les derniers résultats de la vérification de santé.
Prérequis pour les exemples de cet article
- Docker Engine 20.10+ (les versions antérieures peuvent fonctionner, mais Compose v2 est recommandé)
- Docker Compose v2.20+ (pour utiliser
includesi nécessaire) - Un utilisateur avec la permission d’exécuter des commandes Docker (soit root, soit membre du groupe
docker) - Au moins 2 Go d’espace disque libre pour les images et les volumes
- Une connexion Internet pour tirer les images (ou un miroir de registre local)
Plus petit changement justifié
Après avoir enregistré l’état, effectuez un seul changement ciblé à la fois. Par exemple, si vous devez ajuster la variable d’environnement d’un conteneur, modifiez la section environment d’un service dans docker-compose.yml. Ne modifiez pas simultanément les volumes, les réseaux ou les balises d’image. Après chaque modification, recréez uniquement le service concerné avec docker compose up -d --force-recreate <service> et vérifiez.
Chemin de configuration sécurisé
Un chemin de configuration sécurisé signifie que chaque modification est traçable, réversible et testable. Cette section montre comment structurer vos fichiers Compose, gérer les secrets et assurer la persistance des données avant et après les modifications.
Utiliser une configuration Compose en couches
Pour les laboratoires locaux, un modèle courant est un fichier docker-compose.yml de base plus un fichier de surcharge comme docker-compose.override.yml pour les ajustements spécifiques au développeur. Compose fusionne automatiquement les surcharges, vous pouvez donc garder le fichier de base propre.
Fichier de base docker-compose.yml :
services:
web:
image: nginx:1.25
ports:
- "8080:80"
volumes:
- app_data:/usr/share/nginx/html
environment:
- NGINX_HOST=localhost
- NGINX_PORT=80
networks:
- frontend
db:
image: postgres:16
environment:
POSTGRES_DB: myapp
POSTGRES_USER: myuser
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-changeme}
volumes:
- db_data:/var/lib/postgresql/data
networks:
- backend
healthcheck:
test: ["CMD-SHELL", "pg_isready -U myuser -d myapp"]
interval: 10s
timeout: 5s
retries: 5
volumes:
app_data:
db_data:
networks:
frontend:
backend:
Fichier de surcharge docker-compose.override.yml (facultatif) :
services:
web:
ports:
- "8080:80"
environment:
- NGINX_HOST=dev.local
Lorsque vous exécutez docker compose up, les deux fichiers sont fusionnés. La surcharge peut être désactivée avec docker compose -f docker-compose.yml up si vous avez besoin uniquement de la configuration de base.
Utiliser des variables d’environnement et un fichier .env pour les paramètres non secrets
Compose lit automatiquement un fichier .env dans le répertoire du projet pour la substitution de variables dans le fichier Compose. Par exemple, pour définir dynamiquement le port hôte :
.env :
WEB_PORT=8080
POSTGRES_PASSWORD=mysecretpassword
docker-compose.yml :
services:
web:
ports:
- "${WEB_PORT}:80"
environment:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
Ne commitez jamais .env dans le contrôle de version s’il contient de vrais secrets. À la place, commitez .env.example avec des valeurs fictives et documentez les variables requises.
Protéger les secrets avec Docker secrets ou des outils externes
Pour les laboratoires locaux, vous pouvez utiliser Docker secrets en mode Swarm, mais pour un Compose autonome, de meilleures options sont :
- Utiliser un fichier
.envignoré par git (ajoutez.envà.gitignore) - Utiliser le support intégré des secrets de Docker si vous déployez sur Swarm
- Utiliser un gestionnaire de secrets comme HashiCorp Vault ou pass, et injecter les valeurs au moment de l’exécution
- Ne jamais coder en dur des mots de passe ou des clés API dans le fichier Compose
Exemple d’ajouts à .gitignore :
.env
docker-compose.override.yml
Vérifier la configuration avant de l’appliquer
Avant de recréer les conteneurs, vérifiez la configuration résolue avec docker compose config. Cela montre le fichier Compose fusionné avec les variables substituées, ce qui aide à détecter les fautes de frappe et les surcharges non intentionnelles.
docker compose config
Exemple de sortie :
services:
web:
image: nginx:1.25
ports:
- published: 8080
target: 80
volumes:
- app_data:/usr/share/nginx/html:rw
...
Si vous voyez un avertissement concernant une variable non définie, corrigez le fichier .env ou définissez une valeur par défaut dans le fichier Compose.
Bonnes pratiques de persistance des données
Avant de modifier la configuration d’un conteneur, confirmez où les fichiers sont stockés. Un volume nommé tel que app_data:/var/lib/app est géré par Docker et est généralement plus facile à réutiliser lors des reconstructions de conteneurs. Un montage de type bind comme ./data:/var/lib/app mappe directement un répertoire hôte et est utile pour le développement local, mais il peut exposer des problèmes de permissions, de portabilité et de sauvegarde si le même chemin n’existe pas sur une autre machine.
Dans l’exemple ci-dessus, app_data et db_data sont des volumes nommés. Testez la persistance avec un test de redémarrage :
- Créez des données :
docker compose exec db psql -U myuser -d myapp -c "CREATE TABLE test(id int); INSERT INTO test VALUES (1);"
- Arrêtez et supprimez les conteneurs :
docker compose down
- Redémarrez :
docker compose up -d
- Vérifiez que les données sont toujours là :
docker compose exec db psql -U myuser -d myapp -c "SELECT * FROM test;"
Sortie attendue :
id
----
1
(1 row)
Si les données disparaissent, le service écrivait probablement dans le système de fichiers du conteneur au lieu d’un volume ou d’un montage. Inspectez avec docker inspect <container> --format '{{json .Mounts}}' pour voir les montages réels.
Vérification et diagnostics
La vérification prouve qu’une modification a atteint l’état souhaité sans effets secondaires. Les diagnostics vous aident à comprendre ce qui s’est passé lorsque ce n’est pas le cas. Cette section vous donne des commandes concrètes et des sorties attendues.
Vérifier l’état et la santé des conteneurs
Après docker compose up -d, attendez quelques secondes et vérifiez docker compose ps. Cherchez la colonne STATUS indiquant Up et l’état de santé si défini.
docker compose ps
Exemple :
NAME COMMAND SERVICE STATUS PORTS
app-db-1 "docker-entrypoint.s…" db running (healthy) 0.0.0.0:5432->5432/tcp
app-web-1 "/docker-entrypoint.…" web running 0.0.0.0:8080->80/tcp
Si une vérification de santé est configurée, docker inspect --format '{{json .State.Health}}' app-db-1 donne un JSON avec "Status":"healthy" et les dernières entrées du journal.
Lire les journaux pour les signaux de défaillance
docker compose logs -f <service> suit les journaux. Pour un aperçu rapide des 100 dernières lignes :
docker compose logs --tail 100 web
Lors du débogage des échecs de démarrage, les journaux montrent souvent l’erreur exacte. Par exemple, si le service web ne peut pas se connecter à la base de données, vous pourriez voir :
web_1 | Error: connect ECONNREFUSED 127.0.0.1:5432
Corrigez le réseau ou l’environnement et recréez le service.
Exécuter des commandes à l’intérieur des conteneurs sans modifier l’image
docker compose exec <service> sh ouvre un shell dans le conteneur en cours d’exécution. Cela est utile pour vérifier les fichiers de configuration, tester la connectivité ou exécuter des diagnostics :
docker compose exec web sh
À l’intérieur du conteneur, vous pouvez exécuter :
# Vérifier la configuration nginx
nginx -t
# Tester les ports en écoute
netstat -tulpn | grep 80
Si le conteneur est basé sur une image minimale sans shell, utilisez docker compose run --rm <service> <command> à la place, mais sachez que cela crée un nouveau conteneur.
Inspecter les montages, les réseaux et l’environnement
docker inspect <container> fournit une mine d’informations. Utilisez des modèles de format pour extraire ce dont vous avez besoin :
# Montages
docker inspect app-db-1 --format '{{json .Mounts}}'
# Réseaux
docker inspect app-db-1 --format '{{json .NetworkSettings.Networks}}'
# Variables d’environnement
docker inspect app-db-1 --format '{{range .Config.Env}}{{println .}}{{end}}'
Exemple de sortie des montages pour le conteneur db :
[{"Type":"volume","Name":"app_db_data","Source":"/var/lib/docker/volumes/app_db_data/_data","Destination":"/var/lib/postgresql/data","Driver":"local","Mode":"z","RW":true,"Propagation":""}]
Cela confirme que les fichiers de la base de données sont dans un volume nommé, pas dans le stockage éphémère du conteneur.
Tester la connectivité de l’application
Pour le service web, utilisez curl depuis l’hôte ou depuis un autre conteneur sur le même réseau :
Depuis l’hôte :
curl -I http://localhost:8080
Attendu :
HTTP/1.1 200 OK
Server: nginx/1.25.3
Depuis le conteneur db vers le web ? Non applicable, mais testez la connectivité db depuis web :
docker compose exec web sh -c "nc -zv db 5432"
Attendu si nc est installé :
db (172.18.0.2:5432) open
Sinon, installez netcat dans l’image ou utilisez des alternatives ping et telnet.
Modes de défaillance et reprise
Les échecs sont inévitables. Un bon laboratoire inclut des tests d’échec délibérés et des étapes de reprise documentées. Cette section couvre les scénarios de défaillance courants et comment récupérer en toute sécurité.
Modes de défaillance courants
- Échec du tirage d’image - souvent dû à des problèmes réseau, à l’authentification du registre ou à une faute de frappe dans le nom de l’image.
- Symptôme :
docker compose upéchoue avecError response from daemon: pull access denied for ... - Reprise : vérifiez
docker loginsi vous utilisez un registre privé, vérifiez le nom/la balise de l’image, ou utilisez un miroir. Pour les images publiques, réessayez plus tard ou vérifiez le statut de Docker Hub.
- Conflit de port - le port hôte est déjà utilisé.
- Symptôme :
Error starting userland proxy: listen tcp4 0.0.0.0:8080: bind: address already in use - Reprise : trouvez le processus utilisant le port (
sudo lsof -i :8080ousudo ss -tulpn | grep 8080), arrêtez-le ou modifiez le mappage de port Compose. Utilisez127.0.0.1:8080:80pour lier uniquement à localhost si vous n’avez pas besoin d’accès externe.
- Erreur de configuration - fichier Compose invalide ou option non prise en charge.
- Symptôme :
docker compose configrenvoie des erreurs, ouupéchoue avec une erreur d’analyse. - Reprise : exécutez
docker compose configpour voir la ligne d’erreur. Corrigez la syntaxe YAML ou l’option, puis réexécutez. Problèmes courants : indentation incorrecte, cléservices:manquante, ou utilisation de la syntaxe v1.
- Perte de données due à la recréation du conteneur - lorsqu’un conteneur est recréé sans volume ni montage.
- Symptôme : après
docker compose up --force-recreate, les données sont manquantes. - Reprise : si le conteneur avait un volume, les données sont en sécurité. S’il utilisait la couche inscriptible du conteneur, vous pouvez récupérer les données de l’ancien conteneur s’il existe toujours (
docker ps -apour le trouver, puisdocker cpou le commiter). Pour prévenir, utilisez toujours des volumes pour les données persistantes.
- Échec de la vérification de santé - le conteneur est en marche mais en mauvaise santé, ce qui fait échouer les services dépendants.
- Symptôme :
STATUSafficherunning (unhealthy). - Reprise : vérifiez
docker inspect --format '{{json .State.Health}}' <container>pour voir la vérification de santé qui échoue. Ensuite, vérifiez les journaux et corrigez le problème sous-jacent (par exemple, base de données pas prête, dépendance manquante). Ajustez les paramètres de vérification de santé s’ils sont trop stricts.
Workflow de reprise
- Identifiez le service défaillant :
docker compose pspour voir l’état. - Lisez les journaux :
docker compose logs <service>. - Inspectez la configuration :
docker compose configpour le service. - Faites une correction (modifiez le fichier Compose, changez une variable d’environnement, mettez à jour un volume, etc.).
- Recréez uniquement ce service :
docker compose up -d --force-recreate <service>. - Vérifiez la santé et la fonctionnalité de l’application.
- Documentez l’incident et la correction dans vos notes de laboratoire.
Exemple : reprise après une mauvaise variable d’environnement
Supposons que vous ayez accidentellement défini POSTGRES_PASSWORD sur une chaîne vide. Le conteneur db démarre sans mot de passe, et l’application web ne peut pas s’authentifier.
Symptôme :
web_1 | FATAL: password authentication failed for user "myuser"
Reprise :
- Vérifiez l’environnement actuel :
docker compose exec db env | grep POSTGRES_PASSWORD - Corrigez le fichier
.envpour définir un mot de passe fort. - Recréez le service db :
docker compose up -d --force-recreate db - Vérifiez :
docker compose exec db psql -U myuser -d myapp -c "SELECT 1;"devrait réussir.
Liste de contrôle des opérations
Utilisez cette liste de contrôle avant et après chaque modification de votre laboratoire local Docker Compose.
Avant toute modification
- [ ] Enregistrez les versions actuelles de Docker et Compose.
- [ ] Exécutez
docker compose pset notez les états des conteneurs. - [ ] Sauvegardez toutes les données importantes dans les volumes (par exemple,
docker run --rm -v app_db_data:/data -v $(pwd):/backup alpine tar czf /backup/db_backup.tar.gz -C /data .). - [ ] Examinez le fichier Compose avec
docker compose configet confirmez qu’aucune modification non intentionnelle n’est présente. - [ ] Assurez-vous que tous les secrets sont dans
.envou un gestionnaire externe, pas codés en dur. - [ ] Identifiez le ou les services exacts qui seront affectés.
- [ ] Préparez un plan de retour en arrière (par exemple, annulez le commit git ou gardez un fichier Compose de sauvegarde).
Après la modification
- [ ] Exécutez
docker compose up -d(ou--force-recreatesi nécessaire). - [ ] Vérifiez
docker compose pspour l’état et la santé attendus. - [ ] Exécutez
docker compose logs <service>pour détecter les erreurs immédiates. - [ ] Vérifiez la fonctionnalité de l’application (par exemple, endpoint
curl, exécutez une requête DB). - [ ] Testez la persistance des données si des volumes ont été impliqués (test de redémarrage).
- [ ] Mettez à jour la documentation ou les runbooks avec le nouvel état.
- [ ] Commitez le fichier Compose final et
.env.exampledans le contrôle de version.
Liste de contrôle de maintenance de routine
- [ ] Tirez les dernières images de base :
docker compose pull(puis recréez si nécessaire). - [ ] Nettoyez les images et conteneurs inutilisés :
docker system prune -a(attention : cela supprime toutes les images inutilisées, pas seulement celles en suspens). - [ ] Vérifiez l’utilisation du disque :
docker system df. - [ ] Examinez les journaux pour les erreurs récurrentes.
- [ ] Faites tourner tous les secrets utilisés dans le laboratoire.
Conclusion
Un laboratoire local Docker Compose n’est aussi sûr que la discipline qui l’entoure. Cet article a fourni une approche structurée : inventoriez l’environnement, suivez un chemin de configuration sécurisé, vérifiez les modifications, comprenez les modes de défaillance et utilisez une liste de contrôle des opérations. Chaque recommandation est limitée à une version, observable et réversible lorsque la technologie le permet.
Copier une commande sans vérifier les prérequis et la sortie attendue n’est pas une procédure d’exploitation. Comme prochaine étape, choisissez une vérification à faible risque de cet article, enregistrez l’état actuel, exécutez la vérification documentée, comparez le résultat avec le signal attendu et passez en revue les dépendances telles que Docker, Linux et Nginx.
Un flux de travail technique fiable rend les échecs visibles, protège les valeurs sensibles, limite les modifications à la ressource prévue et définit la vérification de la reprise avant qu’un incident ne force la décision. Construisez votre laboratoire avec ces principes, et il servira d’environnement digne de confiance pour le développement et les tests.