Introduction
Exécuter des conteneurs en production est simple à déclencher, mais plus difficile à opérer de manière cohérente. Un bon guide de Docker debugging doit montrer quoi configurer, quelle commande prouve que la configuration fonctionne, et à quoi ressemble l'échec quand la configuration est absente ou erronée.
Cet article se concentre sur des cas concrets, y compris pour une petite entreprise ou un responsable marketing impliqué dans l'exploitation. Il relie la théorie aux vérifications locales via docker logs, docker exec, docker inspect et docker stats pour éviter les surprises lors du passage en CI/CD ou en environnement proche production.
Objectif pratique : comprendre les composants en mouvement, les tester en local (local testing), et réduire les production pitfalls en réutilisant le même schéma ailleurs.
Vue d'ensemble du workflow
Pour Docker troubleshooting, procédez ainsi :
- Identifiez la ressource concernée (image, réseau, volume, variable d'environnement, limite CPU/mémoire).
- Notez la modification de configuration qui l'affecte (port publié, HEALTHCHECK, montage, etc.).
- Sélectionnez la commande qui prouve que c'est correctement en place.
Gardez le workflow pragmatique : configurez une chose, observez l'état, puis documentez ce qui casse quand l'élément est manquant, mal orthographié ou différent en production. C'est ici que surgissent les hypothèses cachées : chemins locaux, tags d'images, noms de réseau, fichiers .env, limites de ressources, permissions - chacun peut diverger entre un laptop, un runner CI, et un hôte de production.
Les notions clés sont Docker debugging, docker logs, docker exec, docker inspect et docker stats. Des domaines connexes comme Docker production operations, Docker Compose et Docker networking comptent car le comportement d'un conteneur est rarement isolé : un choix de stockage influence déploiement, débogage, sauvegarde et rollback.
Vérifications rapides utiles :
- Lister l'état et les ports :
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
- Lire les erreurs récentes :
docker logs <container> --tail 100
- Inspecter en profondeur (montages, réseaux, variables, santé) :
docker inspect <container>
- Avec Compose :
docker compose ps
docker compose logs -f <service>
docker compose exec <service> sh
Quand des données sont en jeu, confirmez où elles sont stockées avant de changer un conteneur. Un volume nommé (ex : app_data:/var/lib/app) est géré par Docker et plus facile à réutiliser après reconstruction. Un bind mount (ex : ./data:/var/lib/app) reflète un dossier hôte utile en dev, mais peut exposer des problèmes de permissions, de portabilité et de sauvegarde si le même chemin n'existe pas ailleurs.
Test local proche production : arrêtez le conteneur, recréez-le, et vérifiez que l'application voit encore les fichiers attendus. Si les données disparaissent, l'appli écrivait probablement dans le filesystem du conteneur plutôt que dans un volume ou un mount.
Plan pilote local
- Démarrez un seul service avec une configuration minimale mais réaliste (port exposé, variables, volume nommé).
- Mesurez et consignez ce qui prouve la bonne configuration (commande exacte + sortie clé).
- Ajoutez un redémarrage contrôlé :
docker stoppuis recréation (Compose oudocker runéquivalent) et re-vérification de la persistance. - Notez les divergences attendues entre local et prod (chemins, secrets, limites CPU/mémoire).
Ce plan révèle vite les angles morts (noms de réseau, tags d'images, fichiers .env). Traitez la configuration comme un élément à tester, pas seulement à copier.
Commandes essentielles et vérifications rapides
- État et ports publiés :
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
Recherchez Up, Exited, Restarting, ou Up (unhealthy).
- Journaux applicatifs :
docker logs -f --tail 200 <container>
Ajoutez -t pour horodatage. En cas de redémarrages rapides, combinez avec docker events.
- Exécuter une commande dans le conteneur :
docker exec -it <container> sh # ou bash
Vérifiez réseau et DNS :
cat /etc/hosts
getent hosts <service>
curl -v http://localhost: PORT/health
- Inspection ciblée :
docker inspect --format '{{.State.Status}}' <container>
docker inspect --format '{{.State.Health.Status}}' <container> # si HEALTHCHECK
docker inspect --format '{{json .Mounts}}' <container>
docker inspect --format '{{json .NetworkSettings.Networks}}' <container>
- Ressources en temps réel :
docker stats --no-stream <container>
Utile pour repérer la pression CPU/mémoire/IO. En cas d'OOM, corrélez avec docker events.
- Événements du démon (redémarrages, arrêts, OOM) :
docker events --since 10m --filter container=<container>
Réseau et diagnostics
- Inventaire des réseaux :
docker network ls
- Détails et IP/aliases :
docker network inspect <network>
- Test de connectivité entre services (depuis un conteneur) :
docker exec -it <source> sh -c 'ping -c1 <target> || true'
docker exec -it <source> sh -c 'curl -v http://<target>:<port>/health || true'
- Vérifier la publication de ports hôte :
docker ps --format "table {{.Names}}\t{{.Ports}}"
Confirmez que 0.0.0.0: HOST->CONTAINER/tcp correspond à ce que vous attendez.
Volumes et persistance
- Lister et inspecter :
docker volume ls
docker volume inspect app_data
Le Mountpoint indique l'emplacement géré par Docker sur l'hôte.
- Différences pratiques :
- Volume nommé (ex :
app_data:/var/lib/app) : géré par Docker, simple à réutiliser lors des reconstructions. - Bind mount (ex :
./data:/var/lib/app) : pratique en dev, mais sensible aux permissions et à la portabilité.
- Vérification de reprise :
- Démarrez, écrivez un fichier dans
/var/lib/app. - Redémarrez ou recréez le conteneur.
- Vérifiez la présence du fichier. En cas d'absence, reconfigurez le montage.
- Exemple Compose minimal avec volume nommé :
services:
app:
image: your/image: tag
ports:
- "8080:8080"
volumes:
- app_data:/var/lib/app
volumes:
app_data:
Conteneurs en échec ou « unhealthy »
- Identifier l'état :
docker ps --format "table {{.Names}}\t{{.Status}}"
- Détails d'échec :
docker inspect --format '{{.State.ExitCode}} {{.State.OOMKilled}}' <container>
- Journaux de santé (si HEALTHCHECK) :
docker inspect --format '{{json .State.Health.Log}}' <container>
- Exemple HEALTHCHECK dans un Dockerfile (Dockerfile examples) :
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD curl -f http://localhost:8080/health || exit 1
Si l'état devient unhealthy, consultez les logs de santé et ceux de l'application.
- Déboguer un crash immédiat :
- Lancer un shell au lieu de l'entrée par défaut :
docker run --rm -it --entrypoint sh your/image: tag -c "sleep 600"
Inspectez l'image et les chemins attendus, puis ajustez la commande/ENV.
- Corréler avec les événements système :
docker events --since 15m --filter container=<container>
Utile pour repérer des cycles de redémarrage ou un OOMKilled.
Docker Compose en pratique
- Vue d'ensemble des services :
docker compose ps
- Journaux en continu d'un service :
docker compose logs -f <service>
- Shell dans un service pour tester sans reconstruire l'image :
docker compose exec <service> sh
- Rendre les hypothèses explicites :
- Vérifiez la config effective :
docker compose config
- Confirmez les réseaux et volumes nommés générés par le projet.
Compose permet de déboguer un environnement multi-services sans modifier les images. C'est idéal pour articuler les docker commands autour des dépendances (base de données, cache, API) et garder un troubleshooting reproductible.
Conclusion
Le Docker debugging est plus fiable quand l'équipe traite la configuration comme quelque chose à tester. Le chemin le plus sûr : des exemples petits, des commandes exécutées localement, et une confirmation du comportement attendu avant d'ajouter d'autres services ou de l'automatisation.
Prochaine étape : choisissez un service et documentez les commandes exactes pour le construire, l'exécuter, l'inspecter, l'arrêter et le recréer. Comparez ensuite avec Docker production operations, Docker Compose et Docker networking pour ancrer l'implémentation dans votre modèle d'exploitation.
Un workflow robuste rend l'échec visible : les docker logs sont faciles à trouver, les données persistantes survivent aux reconstructions, et le comportement local est suffisamment proche de la production pour détecter les erreurs tôt. En gardant à l'esprit les outils clés (docker logs, docker exec, docker inspect, docker stats, docker events) et les bonnes pratiques de local testing, vous réduisez les production pitfalls et améliorez votre troubleshooting au quotidien.