E-NO
DevOps 10 min de lecture

Erreurs de configuration Docker Compose avec exemples pratiques

calendar_today Publié : 2026-10-08
update Dernière mise à jour : 2026-10-08
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Erreurs de configuration Docker Compose avec exemples pratiques ».

Introduction

Docker Compose simplifie la gestion d'applications multi-conteneurs, mais sa facilité d'utilisation masque des pièges de configuration qui peuvent entraîner des pertes de données, des interruptions de service ou des vulnérabilités de sécurité. Cet article aborde les erreurs courantes de configuration Docker Compose, en proposant des exemples pratiques et des solutions concrètes pour les développeurs, les ingénieurs DevOps et les équipes techniques de startups.

Nous nous concentrons sur des étapes observables et vérifiables : vérifier l'état actuel avant d'apporter des modifications, utiliser des valeurs par défaut raisonnables, éviter les secrets codés en dur et savoir comment revenir en arrière. Chaque section comprend des extraits de commandes concrets, les sorties attendues et les procédures de récupération.

Inventaire des versions et de l'environnement

Avant de modifier toute configuration Compose, comprenez votre environnement. Différentes versions de Docker Compose ont des capacités et une syntaxe différentes. Exécutez :

docker compose version

Exemple de sortie :

Docker Compose version v2.27.1

Pour Compose v1 (basé sur Python), utilisez docker-compose version. Notez la différence : la v2 est écrite en Go et est un plugin pour la CLI Docker, tandis que la v1 est un binaire autonome. De nombreux exemples en ligne font référence à la v1 ; si vous utilisez la v2, les commandes peuvent nécessiter docker compose (avec un espace) au lieu de docker-compose.

Vérifiez la version du moteur Docker :

docker version --format '{{.Server.Version}}'

Celle-ci doit être compatible avec votre version de Compose.

Inventoriez les conteneurs en cours d'exécution et leur état :

docker compose ps

Cela affiche les services du projet, leur état et les ports exposés. Pour une inspection plus approfondie, utilisez docker inspect sur un conteneur spécifique pour voir les montages, les réseaux et les variables d'environnement (bien que les variables d'environnement puissent être sensibles à moins d'être masquées).

Séparer l'observation de l'intervention

Prenez l'habitude d'enregistrer l'état actuel avant de modifier quoi que ce soit. Par exemple, sauvegardez la configuration actuelle :

docker compose config > compose-backup-$(date +%Y%m%d).yml

Cela vous permet de comparer avec la nouvelle configuration et de revenir en arrière si nécessaire.

Vérification de l'emplacement de stockage des données

Une erreur fréquente est de supposer que les données persistent lors des recréations de conteneurs sans configurer correctement les volumes. Dans Compose, vous pouvez monter un volume nommé ou un montage lié (bind mount). Un volume nommé est géré par Docker et généralement stocké sous /var/lib/docker/volumes/, tandis qu'un montage lié mappe directement un chemin hôte.

Exemple d'extrait Compose avec un volume nommé :

services:
  db:
    image: postgres:16
    volumes:
      - db_data:/var/lib/postgresql/data
volumes:
  db_data:

Avec un montage lié :

volumes:
  - ./data:/var/lib/postgresql/data

Pour vérifier la persistance des données, effectuez un test de redémarrage : arrêtez et supprimez le conteneur, puis relancez-le :

docker compose down
docker compose up -d

Vérifiez ensuite si les données sont toujours accessibles. Si les données disparaissent, le service a probablement écrit dans le système de fichiers éphémère du conteneur au lieu du volume prévu.

Question rapide 1 sur 2

Dans Docker Compose, quel est l'objectif principal de l'élément de niveau supérieur 'secrets' ?

Le passage indique : 'L'élément de niveau supérieur `secrets` définit deux secrets `db_password` et `db_root_password`. Lors du déploiement, Docker crée ces deux secrets et les remplit avec le contenu du fichier spécifié dans le fichier Compose.'

Chemin de configuration sûr

Lorsque vous modifiez des fichiers Compose, suivez une approche systématique pour éviter d'introduire des erreurs.

Valider la configuration avant de l'appliquer

Validez toujours votre fichier Compose avec :

docker compose config

Cela vérifie la syntaxe et résout les variables, affichant la configuration finale. En cas d'erreurs, la commande se termine avec un code non nul et affiche des messages. Par exemple, si vous avez une indentation YAML invalide :

docker compose config

Sortie :

services.db.environment.MYSQL_ROOT_PASSWORD contient un type invalide, il devrait être une chaîne ou un objet

Remarque : docker compose config ne garantit pas que les services fonctionneront correctement ; il vérifie uniquement la syntaxe et le schéma.

Utiliser correctement les variables d'environnement

Au lieu de coder en dur les secrets dans le fichier Compose, utilisez la substitution de variables d'environnement. Dans docker-compose.yml :

services:
  app:
    image: myapp:latest
    environment:
      DB_PASSWORD: ${DB_PASSWORD}

Spécifiez ensuite la valeur dans un fichier .env dans le même répertoire (non versionné) :

DB_PASSWORD=supersecret

Ou définissez-la dans le shell :

export DB_PASSWORD=supersecret

Lorsque vous exécutez docker compose config, la variable sera substituée. Pour éviter d'exposer les secrets, utilisez docker compose config --no-interpolate pour voir le fichier brut sans substitution.

Une erreur courante est d'utiliser $$ (double dollar) pour échapper la substitution de variable lorsque vous souhaitez passer la chaîne littérale. Par exemple, si vous voulez passer un $DB_PASSWORD littéral au conteneur, écrivez $$DB_PASSWORD dans le fichier Compose.

Limiter la portée : utiliser les profils et les fichiers de surcharge

Utilisez les profils Compose pour démarrer optionnellement des services. Par exemple :

services:
  app:
    image: myapp:latest
  debug-tools:
    image: busybox
    profiles: ["debug"]

Avec les profils, docker compose up démarre uniquement app, tandis que docker compose --profile debug up démarre les deux. Cela empêche le démarrage accidentel de services de débogage en production.

Une autre technique consiste à utiliser plusieurs fichiers Compose, comme compose.yaml et compose.override.yaml. Le fichier de surcharge peut spécifier des paramètres spécifiques au développement. Par défaut, si les deux fichiers existent, Compose les fusionne automatiquement ; vous pouvez afficher la configuration fusionnée avec :

docker compose config

Si vous utilisez des noms de fichiers personnalisés, spécifiez-les avec les options -f. Cela vous permet de garder la configuration de base stable et d'ajouter des modifications locales sans toucher au fichier principal.

Apporter des modifications petites et réversibles

Modifiez un paramètre à la fois et testez immédiatement. Par exemple, si vous devez augmenter la limite de mémoire d'un service, modifiez le fichier Compose :

services:
  app:
    deploy:
      resources:
        limits:
          memory: 512M

Appliquez :

docker compose up -d

Vérifiez ensuite si le service est sain et si l'utilisation de la mémoire est dans les limites. Si des problèmes surviennent, annulez facilement la modification en défaisant la modification et en exécutant à nouveau docker compose up -d.

Vérification et diagnostics

Après avoir appliqué les modifications, vérifiez que le système se comporte comme prévu.

Vérifier l'état des services

Utilisez docker compose ps pour voir si les conteneurs sont en cours d'exécution :

docker compose ps

Exemple de sortie :

NAME                COMMAND                  SERVICE             STATUS              PORTS
myapp_app_1         "python app.py"          app                 running             0.0.0.0:8000->8000/tcp
myapp_db_1          "docker-entrypoint.s…"   db                  running             5432/tcp

Si un conteneur est exited ou restarting, examinez les journaux.

Lire efficacement les journaux

Utilisez docker compose logs pour afficher les journaux :

docker compose logs app

Suivez les journaux en temps réel :

docker compose logs -f app

Si vous avez besoin de voir uniquement les lignes récentes :

docker compose logs --tail=100 app

Les indicateurs d'échec courants dans les journaux incluent les exceptions, les erreurs de connexion refusée ou les messages de boucle de crash. Par exemple, si la base de données est injoignable, vous pourriez voir :

ERROR: could not connect to database: connection refused

Inspecter les détails du conteneur

Utilisez docker inspect pour obtenir des informations détaillées sur un conteneur, y compris son état de santé, ses montages et son environnement :

docker inspect myapp_app_1

Pour extraire des champs spécifiques :

docker inspect --format '{{.State.Health.Status}}' myapp_app_1

Si l'état de santé est unhealthy, examinez la configuration du healthcheck.

Définir des healthchecks

Ajoutez des healthchecks à vos services pour détecter automatiquement les défaillances. Exemple pour une application web :

services:
  web:
    image: nginx:alpine
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

Avec les healthchecks, docker compose ps affiche l'état de santé, et vous pouvez utiliser docker compose up --wait pour bloquer jusqu'à ce que les services soient sains.

Déboguer à l'intérieur du conteneur

Utilisez docker compose exec pour exécuter des commandes dans un conteneur en cours d'exécution :

docker compose exec app sh

Cela vous donne un shell dans le conteneur pour vérifier les fichiers, les processus ou tester la connectivité. Pour des commandes ponctuelles :

docker compose exec app env

Remarque : exec nécessite que le conteneur soit en cours d'exécution ; si le conteneur se termine immédiatement, vous devrez peut-être remplacer le point d'entrée :

docker compose run --entrypoint sh app

Modes de défaillance et récupération

Même avec une planification minutieuse, des problèmes surviennent. Voici des scénarios de défaillance typiques et comment récupérer.

Le conteneur se termine immédiatement

Si un conteneur démarre et se termine avec le code 0 ou non nul, vérifiez les journaux :

docker compose logs <service>

Souvent, la commande est mal configurée. Dans Compose, l'option command remplace le CMD par défaut. Par exemple, si vous avez :

services:
  app:
    image: alpine
    command: echo "hello"

Le conteneur exécutera echo et se terminera. Pour le maintenir en vie, vous pourriez avoir besoin d'un processus de longue durée. Récupération : ajustez la command pour un processus de premier plan.

Conflits de ports

Si un service ne parvient pas à se lier à un port, vous verrez une erreur comme :

Error starting userland proxy: listen tcp4 0.0.0.0:80: bind: address already in use

Identifiez quel processus utilise le port sur l'hôte :

sudo lsof -i :80

Ou sur Linux :

sudo ss -tulpn | grep :80

Ensuite, arrêtez le processus en conflit ou modifiez le port hôte dans le fichier Compose :

ports:
  - "8080:80"

Erreurs de montage de volume

Si un chemin de montage lié n'existe pas sur l'hôte, Docker peut le créer en tant que répertoire avec la propriété root, ce qui entraîne des problèmes de permissions à l'intérieur du conteneur. Par exemple :

volumes:
  - ./logs:/app/logs

Si ./logs n'existe pas, Docker le crée, mais l'utilisateur du conteneur peut ne pas avoir les permissions d'écriture. Récupération : créez le répertoire avec des permissions appropriées avant de démarrer :

mkdir -p logs && chmod 777 logs

Ou ajustez l'utilisateur du conteneur pour qu'il corresponde.

Variable d'environnement non substituée

Si vous référencez une variable dans le fichier Compose mais qu'elle n'est pas définie, docker compose config émettra un avertissement ou une erreur. Par exemple :

environment:
  - DATABASE_URL=${DATABASE_URL}

Si DATABASE_URL n'est pas définie, le conteneur reçoit une chaîne vide. Pour éviter cela, définissez une valeur par défaut dans le fichier Compose :

environment:
  - DATABASE_URL=${DATABASE_URL:-postgres://localhost:5432}

Vérifiez ensuite avec docker compose config.

Stratégie de récupération : retour en arrière

Soyez toujours en mesure de revenir à un état connu et fonctionnel. Cela signifie :

  • Gardez un contrôle de version pour vos fichiers Compose (par exemple, Git).
  • Avant d'apporter des modifications, créez une sauvegarde de la configuration actuelle et, le cas échéant, des données.
  • Utilisez docker compose config pour sauvegarder la configuration entièrement résolue pour référence future.
  • Si une modification casse l'application, récupérez la version précédente et appliquez-la : git checkout -- docker-compose.yml puis docker compose up -d.

Pour les données, si vous utilisez des volumes nommés, envisagez des instantanés ou des sauvegardes. Par exemple, pour sauvegarder une base de données PostgreSQL dans un volume, vous pourriez exécuter :

docker compose exec db pg_dump -U postgres mydb > backup.sql

Puis pour restaurer :

cat backup.sql | docker compose exec -T db psql -U postgres mydb

Question rapide 2 sur 2

Qu'indique l'argument `-` dans la commande `openssl rand -base64 20 | docker secret create mysql_password -` ?

Le passage explique : 'Le dernier argument est défini sur `-`, ce qui indique que l'entrée est lue depuis l'entrée standard.'

Pièges courants et comment les éviter

Cette section regroupe les erreurs fréquentes, pourquoi elles se produisent et comment les prévenir ou les récupérer.

Piège 1 : Utiliser le tag latest pour les images

Utiliser image: myapp:latest peut entraîner un comportement imprévisible car latest peut changer de manière inattendue. Cela rend le retour en arrière difficile et nuit à la reproductibilité.

Comment éviter : Épinglez des versions d'image spécifiques, par exemple image: myapp:1.2.3. Utilisez un digest pour une immuabilité encore plus forte : myapp@sha256:....

Piège 2 : Coder en dur les secrets dans les fichiers Compose

Stocker des mots de passe ou des clés API directement dans docker-compose.yml est un risque de sécurité, surtout si le fichier est versionné dans un dépôt.

Comment éviter : Utilisez des variables d'environnement ou des secrets Docker. Pour le développement local, utilisez un fichier .env qui est gitignoré. Pour la production, utilisez un gestionnaire de secrets.

Piège 3 : Mal comprendre les types de volumes

Utiliser des montages liés quand vous vouliez des volumes nommés (ou vice versa) peut entraîner une perte de données ou des problèmes de permissions. Les montages liés sont spécifiques à l'hôte ; les volumes nommés sont portables et gérés par Docker.

Comment éviter : Définissez clairement le type et le but du volume. Utilisez des volumes nommés pour les données d'application persistantes, des montages liés pour le développement où vous avez besoin de la synchronisation du code en direct.

Piège 4 : Ne pas définir de politiques de redémarrage

Par défaut, les conteneurs ne redémarrent pas automatiquement sauf si vous spécifiez une politique de redémarrage. Si un conteneur plante, il reste arrêté.

Comment éviter : Définissez restart: unless-stopped ou restart: always pour les services de production. Exemple :

services:
  app:
    restart: unless-stopped

Piège 5 : Ignorer les limites de ressources

Sans limites, un conteneur peut consommer toutes les ressources de l'hôte, affectant les autres services.

Comment éviter : Définissez des limites de mémoire et de CPU en utilisant la clé deploy (pour Swarm) ou mem_limit, cpus (pour non-Swarm). Exemple :

services:
  app:
    mem_limit: 512m
    cpus: 0.5

Piège 6 : Mal configurer les réseaux

Les services peuvent ne pas communiquer parce qu'ils sont sur des réseaux différents ou que les alias de réseau sont incorrects.

Comment éviter : Définissez explicitement les réseaux dans le fichier Compose et attachez les services aux réseaux appropriés. Utilisez docker compose exec pour tester la connectivité avec ping ou curl.

Piège 7 : Ne pas sauvegarder les données

Les données dans les conteneurs ou les volumes peuvent être perdues si vous supprimez des volumes par inadvertance.

Comment éviter : Sauvegardez régulièrement les volumes en utilisant docker run --rm -v volume_name:/data -v $(pwd):/backup alpine tar czf /backup/backup.tar.gz -C /data .

Piège 8 : Négliger les limitations de depends_on

depends_on contrôle uniquement l'ordre de démarrage ; il n'attend pas que la dépendance soit prête (par exemple, que la base de données accepte les connexions).

Comment éviter : Utilisez des healthchecks et depends_on avec condition: service_healthy (Compose v2.1+). Exemple :

services:
  web:
    depends_on:
      db:
        condition: service_healthy
  db:
    image: postgres
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

Liste de contrôle opérationnelle

Utilisez cette liste avant et après avoir apporté des modifications de configuration Compose. Attribuez un responsable (par exemple, ingénieur DevOps) et une fréquence de révision.

ÉtapeActionCommande/DétailResponsableRévision
1Enregistrer la version actuelle de Composedocker compose versionResponsable DevOpsÀ chaque modification
2Sauvegarder la configuration actuelledocker compose config > backup.ymlResponsable DevOpsÀ chaque modification
3Valider la nouvelle configurationdocker compose configDéveloppeurÀ chaque modification
4Appliquer en mode simulation (si disponible)docker compose up --no-startDéveloppeurÀ chaque modification
5Appliquer les modificationsdocker compose up -dResponsable DevOpsÀ chaque modification
6Vérifier l'état des servicesdocker compose psDéveloppeurImmédiatement
7Vérifier les journaux pour les erreursdocker compose logs --tail=50DéveloppeurImmédiatement
8Tester la fonctionnalité de l'applicationTests manuels ou automatisésIngénieur QAAprès chaque déploiement
9Vérifier la persistance des donnéesdocker compose down && docker compose up -d puis vérifier les donnéesResponsable DevOpsMensuellement
10Examiner la sécurité (secrets, permissions)docker compose config --no-interpolate pour vérifier les secretsAgent de sécuritéTrimestriellement

Chaque élément doit avoir un responsable nommé. Par exemple, le responsable DevOps (par exemple, « Priya Shah, responsable de l'ingénierie ») est responsable des sauvegardes de configuration et de l'application des modifications. Les intervalles de révision peuvent être ajustés en fonction du risque, mais les paramètres critiques doivent être examinés après chaque modification.

Conclusion

Les erreurs de configuration Docker Compose peuvent entraîner des temps d'arrêt et des pertes de données, mais elles sont évitables avec des pratiques systématiques. En validant les configurations, en gérant correctement les volumes et les variables d'environnement, et en ayant un plan de retour en arrière, vous pouvez réduire considérablement les risques.

Observez toujours avant de changer, apportez des modifications petites et réversibles, et vérifiez le résultat avec des commandes concrètes. Tenez une liste de contrôle et attribuez des responsabilités pour garantir la responsabilisation. Pour approfondir, explorez la documentation officielle de Docker sur la référence des fichiers Compose, les healthchecks et la gestion des secrets.

Prochaine étape : choisissez une amélioration à faible risque de cet article, comme l'ajout de healthchecks à un service, et implémentez-la dans un environnement de développement. Enregistrez l'état actuel, appliquez la modification et vérifiez le comportement attendu. Documentez tout problème pour référence future.

En adoptant ces pratiques, vous construirez un environnement conteneurisé plus résilient.

Recherches connexes

Score de qualité de l’article

Utilité pour le lecteur 100%
  • check_circle Guide prêt à lire
  • check_circle Exemples pratiques inclus
  • check_circle URL d’article optimisée pour le SEO