E-NO
DevOps 10 min de lecture

Débogage de conteneurs Docker : erreurs de configuration et correctifs pratiques

calendar_today Publié : 2026-09-28
update Dernière mise à jour : 2026-09-28
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Débogage de conteneurs Docker : erreurs de configuration et correctifs pratiques ».

Introduction

Déboguer un conteneur Docker mal configuré consiste rarement à trouver une commande magique. Il s'agit de construire une séquence reproductible : observer l'état actuel, identifier le plus petit changement possible, l'appliquer de manière contrôlée, vérifier le résultat et savoir revenir en arrière si la situation empire. Ce guide passe en revue les erreurs de configuration courantes — réseau, montages, variables d'environnement, contrôles de santé et limites de ressources — en utilisant des commandes réelles et des sorties attendues pour passer rapidement du symptôme à la solution.

Nous nous concentrerons sur un débogage pratique, orienté production. L'objectif est la sécurité opérationnelle : ne jamais modifier un conteneur en cours d'exécution à l'aveugle, protéger les secrets, limiter le rayon d'impact et toujours avoir un plan de récupération documenté avant d'en avoir besoin.

Inventaire de la version et de l'environnement

Avant de toucher à quoi que ce soit, sachez exactement avec quoi vous travaillez. Exécutez ces commandes en lecture seule et capturez la sortie dans vos notes d'incident avec un horodatage.

Vérifiez la version de Docker et les informations du démon :

docker version

La sortie attendue inclut les versions client et serveur. Par exemple :

Client: Docker Engine - Community
 Version:           24.0.7
 API version:       1.43
 Go version:        go1.20.10
 Git commit:        311b9ff
 Built:             Thu Oct 26 09:08:15 2023
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          24.0.7

Si les versions client et serveur diffèrent de manière significative, certaines fonctionnalités peuvent se comporter de manière inattendue. Mettez à niveau ou rétrogradez pour correspondre au standard de l'équipe.

Listez les conteneurs en cours d'exécution avec les métadonnées clés :

docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}\t{{.Image}}"

Exemple de résultat :

NAMES                STATUS                    PORTS                     IMAGE
web-app              Up 2 hours (unhealthy)   0.0.0.0:8080->80/tcp      nginx:1.25
postgres-db          Up 5 hours                0.0.0.0:5432->5432/tcp    postgres:15

Notez l'état de santé. Un conteneur « unhealthy » est un indice, pas un verdict — il peut encore servir du trafic tout en échouant à son contrôle de santé.

Inspectez un conteneur spécifique pour les montages, réseaux, variables d'environnement et configuration de santé :

docker inspect web-app

Cela produit un gros objet JSON. Filtrez les parties dont vous avez besoin :

docker inspect web-app --format '{{json .Mounts}}' | jq
docker inspect web-app --format '{{json .NetworkSettings.Networks}}' | jq
docker inspect web-app --format '{{json .Config.Env}}' | jq
docker inspect web-app --format '{{json .Config.Healthcheck}}' | jq

Chaque commande renvoie des données structurées. Par exemple, la sortie des montages pour un conteneur avec un volume nommé et un montage bind pourrait ressembler à :

[
  {
    "Type": "volume",
    "Name": "web-app-data",
    "Source": "/var/lib/docker/volumes/web-app-data/_data",
    "Destination": "/var/www/html",
    "Mode": "",
    "RW": true,
    "Propagation": "rprivate"
  },
  {
    "Type": "bind",
    "Source": "/home/user/config",
    "Destination": "/etc/app/config",
    "Mode": "ro",
    "RW": false,
    "Propagation": "rprivate"
  }
]

Portez une attention particulière au champ RW : un montage bind en lecture seule fera échouer les écritures avec une erreur de permission si l'application s'attend à modifier ces fichiers.

Pour les projets Compose, obtenez une vue globale du projet :

docker compose ps
docker compose config --services
docker compose config --volumes

Ces commandes confirment les services définis dans votre fichier compose et si Docker voit les volumes que vous attendez.

Persistance des données avant tout changement

L'une des erreurs de configuration les plus courantes est la perte de données lors de la recréation d'un conteneur. Avant de poursuivre le débogage, confirmez où vivent les données persistantes :

  • Volume nommé : géré par Docker, facile à réutiliser. Exemple d'extrait Compose :
services:
  app:
    image: myapp:1.2
    volumes:
      - app_data:/var/lib/app
volumes:
  app_data:
  • Montage bind : mappe directement un chemin de l'hôte. Utile pour le développement mais peut échouer en production si le chemin hôte n'existe pas sur toutes les machines.

Effectuez un test de redémarrage dans un environnement de staging :

  1. Arrêtez le conteneur : docker stop web-app
  2. Supprimez-le : docker rm web-app
  3. Recréez-le à partir du même fichier compose ou de la même commande run.
  4. Vérifiez si les données sont toujours présentes : docker exec web-app ls /var/lib/app

Si les fichiers manquent, l'application écrivait probablement dans la couche inscriptible du conteneur au lieu d'un volume ou d'un montage. Corrigez le Dockerfile ou le fichier compose pour monter un volume à ce chemin.

Question rapide 1 sur 2

Quel est l'objectif principal de la commande `docker compose config` ?

Le passage indique que `docker compose config` ne nécessite pas que la stack soit en cours d'exécution — il fonctionne uniquement à partir de vos fichiers et affiche la configuration entièrement résolue.

Chemin de configuration sûr

Lorsque vous avez identifié une erreur de configuration probable, suivez un processus de changement chirurgical. Ne modifiez jamais les fichiers à l'intérieur d'un conteneur en cours d'exécution avec docker exec vi — ce changement disparaît à la recréation du conteneur et n'est pas suivi.

Utilisez correctement les variables d'environnement

Une erreur fréquente est de passer des secrets via des variables d'environnement en clair dans une commande docker run ou un fichier compose, où ils sont visibles dans docker inspect et les listes de processus.

Mauvaise pratique :

docker run -e DATABASE_PASSWORD=supersecret myapp

docker inspect affichera ce mot de passe en clair.

Mieux : utilisez les secrets Docker (pour Swarm) ou un fichier de secrets monté en volume en lecture seule. Exemple de fichier compose avec montage d'un fichier de secret :

services:
  app:
    image: myapp:1.2
    secrets:
      - db_password
secrets:
  db_password:
    file: ./secrets/db_password.txt

À l'intérieur du conteneur, le secret apparaît à /run/secrets/db_password. L'application lit à partir de ce chemin.

Changez une variable à la fois

Si vous soupçonnez qu'une variable d'environnement est incorrecte, modifiez uniquement cette variable et redémarrez le conteneur. Ne regroupez pas de modifications sans rapport.

Pour un conteneur unique :

docker stop web-app
docker rm web-app
docker run -d --name web-app \
  -e APP_ENV=production \
  -e DATABASE_URL=postgres://db:5432/app \
  -p 8080:80 \
  myapp:1.2

Ensuite, vérifiez les journaux et la santé :

docker logs web-app --tail 50
docker inspect web-app --format '{{.State.Health.Status}}'

Si l'état de santé n'est pas « healthy » en une minute, vous savez que la nouvelle variable d'environnement a contribué au problème.

Pour Compose, modifiez docker-compose.yml, puis recréez uniquement le service affecté :

docker compose up -d --force-recreate app

--force-recreate garantit que le conteneur est reconstruit avec la nouvelle configuration au lieu de réutiliser l'ancienne.

Plan de retour en arrière

Avant d'appliquer un changement, écrivez la commande exacte de retour en arrière dans vos notes. Pour un service Compose, la configuration précédente est dans votre contrôle de version — il suffit de récupérer le commit précédent et de relancer docker compose up -d. Pour un docker run manuel, vous pouvez inspecter la configuration actuelle du conteneur avant suppression avec :

docker inspect web-app --format '{{json .Config}}' > web-app-config-backup.json

Ensuite, si nécessaire, reconstruisez la commande run à partir de ce JSON. Mieux encore, conservez toutes les définitions de conteneurs dans un fichier compose ou un script sous contrôle de version afin que le retour en arrière soit fiable.

Vérification et diagnostics

Après tout changement, vérifiez que le conteneur se comporte comme prévu. Ne vous fiez pas à « il a démarré » — vérifiez la fonctionnalité réelle et l'utilisation des ressources.

Vérifiez les journaux pour les motifs d'erreur

docker logs web-app --tail 200

Cherchez des exceptions récurrentes, des messages de connexion refusée ou des erreurs de configuration invalide. Pour un conteneur qui plante immédiatement après le démarrage, utilisez :

docker logs web-app

Si le conteneur a redémarré plusieurs fois, ajoutez des horodatages :

docker logs --timestamps web-app

Pour un conteneur qui se termine immédiatement, exécutez-le au premier plan avec un shell de substitution pour déboguer les problèmes de démarrage :

docker run --rm -it myapp:1.2 /bin/sh

Ensuite, exécutez manuellement la commande de démarrage de l'application pour voir l'erreur.

Testez la connectivité réseau

Depuis l'intérieur d'un conteneur en cours d'exécution, testez la résolution DNS et la connectivité TCP :

docker exec web-app ping -c 3 database

Sortie attendue si le DNS fonctionne :

PING database (172.18.0.2) 56(84) bytes of data.
64 bytes from database (172.18.0.2): icmp_seq=1 ttl=64 time=0.089 ms

Si le nom ne se résout pas, le conteneur n'est peut-être pas sur le même réseau défini par l'utilisateur. Vérifiez les réseaux :

docker network ls
docker network inspect bridge

Pour un conteneur attaché à un réseau spécifique, assurez-vous que les services Compose partagent ce réseau.

Vérifiez les conflits de liaison de port :

docker ps --format "table {{.Names}}\t{{.Ports}}"

Si un autre conteneur utilise déjà le port hôte que vous voulez, vous verrez une erreur de liaison de port dans les journaux.

Contrôles de santé et disponibilité

Un contrôle de santé mal configuré peut marquer un conteneur sain comme malsain, déclenchant des redémarrages inutiles. Inspectez la définition du contrôle de santé :

docker inspect web-app --format '{{json .Config.Healthcheck}}' | jq

Exemple de sortie :

{
  "Test": ["CMD-SHELL", "curl -f http://localhost/ || exit 1"],
  "Interval": 30000000000,
  "Timeout": 5000000000,
  "Retries": 3,
  "StartPeriod": 60000000000
}

Les intervalles sont en nanosecondes. Une période de démarrage de 60 secondes (60 000 000 000 ns) peut être trop courte si votre application met plus de temps à s'initialiser. Ajustez dans votre Dockerfile ou fichier compose :

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost/"]
  interval: 30s
  timeout: 5s
  retries: 3
  start_period: 120s

Après la mise à jour, recréez le conteneur et surveillez l'état de santé au fil du temps :

watch -n 5 'docker inspect web-app --format "{{.State.Health.Status}}"'

Modes de défaillance et récupération

Examinons des erreurs de configuration spécifiques et comment récupérer de chacune.

Erreur 1 : Montage de volume manquant entraînant une perte de données

Symptôme : Après la recréation du conteneur, tous les fichiers téléchargés par les utilisateurs ont disparu. Pourquoi cela arrive : L'application a écrit dans un répertoire à l'intérieur du système de fichiers du conteneur, pas dans un volume monté. Récupération : Vérifiez le système de fichiers de l'ancien conteneur (s'il est encore disponible) avec docker cp pour récupérer les fichiers avant de le supprimer. Ensuite, mettez à jour votre fichier compose pour ajouter un volume nommé au chemin de données de l'application. Recréez le conteneur et vérifiez la persistance avec un test de redémarrage.

Erreur 2 : Fautes de frappe dans les variables d'environnement causant des échecs de connexion

Symptôme : L'application ne peut pas se connecter à la base de données, mais le conteneur de base de données est en cours d'exécution. Pourquoi cela arrive : Une faute de frappe dans le nom de la variable d'environnement, par exemple, DATABSE_URL au lieu de DATABASE_URL. Récupération : Inspectez l'environnement du conteneur :

docker exec web-app env | sort

Comparez avec ce que l'application attend. Corrigez le fichier compose ou le Dockerfile, puis recréez le conteneur. Utilisez une bibliothèque de configuration qui valide les variables d'environnement requises au démarrage pour échouer rapidement.

Erreur 3 : Mappage de port incorrect empêchant l'accès externe

Symptôme : Le service fonctionne mais ne peut pas être atteint depuis l'hôte. Pourquoi cela arrive : Soit le mauvais port du conteneur est mappé, soit le port hôte est déjà utilisé. Récupération : Vérifiez les mappages de port réels :

docker port web-app

Comparez avec le port d'écoute de l'application (vérifiez le EXPOSE du Dockerfile ou les journaux de démarrage). Mettez à jour le mappage de port et recréez. Vérifiez avec curl http://localhost:8080.

Erreur 4 : Limites de ressources non définies, le conteneur tue des processus

Symptôme : Le conteneur est tué avec le code de sortie 137 (SIGKILL) sous charge. Pourquoi cela arrive : Le conteneur a dépassé la limite de mémoire (si définie) ou l'hôte a manqué de mémoire. Récupération : Inspectez l'utilisation actuelle des ressources :

docker stats --no-stream

Définissez des limites de mémoire et de CPU appropriées dans votre fichier compose :

services:
  app:
    image: myapp:1.2
    deploy:
      resources:
        limits:
          cpus: '0.50'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M

Recréez et exécutez des tests de charge pour confirmer la stabilité.

Erreur 5 : Utilisation d'une mauvaise image de base ou balise

Symptôme : L'application se comporte différemment en production par rapport au développement, ou des dépendances manquent. Pourquoi cela arrive : Le Dockerfile utilise une balise mutable comme latest, ou l'image de base diffère entre les environnements. Récupération : Épinglez l'image de base à un digest ou une balise de version spécifique dans votre Dockerfile. Reconstruisez l'image, poussez vers le registre et redéployez. Utilisez docker image inspect pour vérifier que l'ID de l'image correspond entre les environnements.

Question rapide 2 sur 2

Après avoir exécuté `docker compose config`, laquelle des affirmations suivantes est vraie à propos de la sortie ?

Le passage note que `${APP_PORT}`, `${REDIS_HOST}` et `${REDIS_PORT}` ont tous été remplacés par les valeurs de votre fichier `.env`.

Pièges courants et comment les éviter

Au-delà des erreurs spécifiques ci-dessus, voici des pièges généraux qui font trébucher les équipes.

Modifier des fichiers à l'intérieur du conteneur

Exécuter docker exec -it web-app bash et modifier un fichier de configuration avec vi ou sed est tentant pour une solution rapide. Mais le changement est perdu à la recréation du conteneur et n'est pas visible pour les autres membres de l'équipe. À la place, montez un fichier de configuration ou utilisez des variables d'environnement, puis recréez.

Ignorer les journaux jusqu'à ce que quelque chose casse

Les journaux sont le premier endroit à regarder, mais de nombreuses équipes ne les collectent pas de manière centralisée. Utilisez les pilotes de journalisation Docker pour transférer les journaux vers un service d'agrégation. Exemple d'extrait compose :

services:
  app:
    image: myapp:1.2
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

Pour un serveur syslog central, passez le pilote à syslog et spécifiez l'adresse. Cela garantit que les journaux sont disponibles même si le conteneur est supprimé.

Ne pas utiliser de fichier .dockerignore

Sans fichier .dockerignore, le contexte de construction peut inclure le répertoire local .git, node_modules ou des secrets, rendant l'image inutilement volumineuse et pouvant fuiter des données sensibles. Créez un fichier .dockerignore à la racine de votre contexte de construction :

.git
node_modules
*.log
.env
secrets

Utilisation excessive de la balise latest

Comme mentionné, latest rend les constructions non reproductibles. Utilisez toujours des balises de version sémantique ou des digests dans les fichiers de déploiement en production. Pour le développement local, latest est acceptable mais évitez-le dans les pipelines CI/CD.

Omettre les contrôles de santé

Sans contrôle de santé, Docker ne peut pas savoir si votre application est vraiment prête. Définissez un contrôle de santé qui teste un point de terminaison critique, pas seulement que le processus est en cours d'exécution. Utilisez start_period pour laisser suffisamment de temps aux applications à démarrage lent.

Liste de contrôle des opérations

Utilisez cette liste de contrôle avant et après tout changement de configuration d'un service conteneurisé. Attribuez chaque élément à une seule personne responsable (pas une équipe) et révisez la liste lors de chaque publication ou revue d'incident.

ÉtapeActionResponsableFréquence
1Enregistrer l'état actuel : sortie de docker ps, docker logs, docker inspectIngénieur d'astreinteAu début de l'incident
2Identifier le changement nécessaire et son rayon d'impactPropriétaire de l'application (par ex., Priya Shah, responsable ingénierie)Pendant la planification du changement
3Sauvegarder les données critiques : docker cp <conteneur>:/chemin /sauvegarde/ si nécessaireAdministrateur de base de donnéesAvant un changement destructif
4Appliquer le plus petit changement possible (une variable d'environnement, un montage, un port)Ingénieur d'astreinteAu moment du changement
5Vérifier la fonctionnalité : journaux, état de santé et réponse réelle du point de terminaisonIngénieur QAImmédiatement après le changement
6Documenter le changement et la procédure de retour en arrière dans le runbookPropriétaire du serviceDans les 24 heures
7Exécuter un test de redémarrage en staging pour confirmer la persistance des données et la configurationPropriétaire de l'applicationAvant le prochain déploiement
8Revoir la chronologie de l'incident et mettre à jour le runbook si nécessaireResponsable ingénierieRevue hebdomadaire des incidents

Cette liste de contrôle garantit qu'aucune étape n'est sautée sous pression. Les responsables sont illustratifs — remplacez-les par les noms et rôles réels de votre organisation.

Conclusion

Déboguer les erreurs de configuration des conteneurs Docker est un processus discipliné, pas un jeu de devinettes. Commencez par un inventaire complet de l'environnement, comprenez l'état actuel, faites un changement minimal à la fois et vérifiez avec des commandes concrètes et des sorties attendues. Ayez toujours un plan de retour en arrière avant de changer quoi que ce soit.

Les flux de travail les plus fiables rendent les défaillances visibles grâce aux journaux et aux contrôles de santé, protègent les valeurs sensibles avec la gestion des secrets, limitent les changements à la ressource prévue et définissent la vérification de la récupération avant qu'un incident ne force une décision. Appliquez la liste de contrôle et les pièges de ce guide pour construire des déploiements de conteneurs plus sûrs et plus résilients. Comme prochaine étape, choisissez un service que vous gérez, parcourez la liste de contrôle des opérations et documentez au moins une procédure de récupération dans le runbook de votre équipe.

Un flux de travail technique fiable rend les défaillances visibles, protège les valeurs sensibles, limite les changements à la ressource prévue et définit la vérification de la récupération avant que l'incident ne force la décision.

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