Intro
Cette version française explique Docker troubleshooting with practical examples avec le même objectif pratique que l article source : aider le lecteur à comprendre le contexte, les décisions à prendre et les points à vérifier avant de passer à l action.
Ce guide montre comment dépanner Docker avec des commandes concrètes, des checklists courtes et de petits workflows de récupération. Il s'adresse aux développeurs, consultants DevOps et équipes de start-up qui veulent des correctifs rapides et sûrs. Vous apprendrez un flux reproductible, verrez des schémas de pannes courants et appliquerez des exemples pratiques qui fonctionnent sur Linux et macOS, ainsi que dans Docker Compose et Kubernetes. Objectif: rendre les problèmes faciles à reproduire, mesurer et résoudre localement avant un déploiement plus large. Les notions clés (Docker troubleshooting, Docker errors, Docker logs, Docker commands, Docker recovery) sont abordées au fil des sections.
Vue d'ensemble du workflow
Utilisez ce flux reproductible pour la plupart des problèmes Docker:
- Vérifier les bases
- Vérifier que Docker tourne:
- Linux:
systemctl status docker - Tous:
docker info - Confirmer que le disque et la mémoire ne sont pas saturés:
df -h,free -m(Linux),docker system df
- Reproduire et capturer le contexte
- Enregistrer la commande exacte, le fichier compose, le tag d'image et le message d'erreur.
- Conserver un plus petit cas de repro si possible.
- Inspecter l'état des conteneurs et des images
docker ps -adocker inspect <container-or-image>
- Lire d'abord les logs
docker logs <container> --since=10m -n 200docker events --since 10m- Logs du démon (Linux):
journalctl -u docker --since "10 min ago"
- Vérifier le réseau
docker network lsdocker network inspect <net>- Test depuis l'hôte:
curl -v http://localhost: PORT - Test depuis un conteneur:
docker exec -it <ctr> sh -c 'curl -v http://service: port'
- Vérifier volumes et permissions
docker inspect -f '{{.Mounts}}' <ctr>ls -lsur les chemins hôtes; identifier les écarts d'UID/GID
- Vérifier build et cache
docker build . --no-cache(pour forcer un rebuild réel)docker history <image>
- Vérifier la pression de ressources
docker stats(vue en direct)ulimit -a; chercher des OOM kills dans les logs
- Corriger, retester et documenter brièvement
- Appliquer la correction minimale viable.
- Reconstruire/recréer uniquement les services affectés.
- Nettoyer en sécurité (optionnel)
- Lister avant de purger:
docker system df - Purge ciblée:
docker image prune -f,docker builder prune -f - Éviter les purges globales destructrices sur des hôtes partagés.
Logs et diagnostics
Commencez par les logs et un instantané rapide de l'état.
Commandes fréquentes:
- Logs de conteneur:
docker logs <ctr>
docker logs -f --since=15m <ctr>
- Logs du démon (Linux):
journalctl -u docker -n 200 --no-pager
- Chronologie d'événements en direct:
docker events --since 30m
- État et santé:
docker inspect -f '{{.State.Status}} {{.State.Health.Status}}' <ctr>
- Réseau:
docker network ls
docker network inspect <net>
- Compose:
docker compose ps
docker compose logs -f --since=10m
Astuce: capturez les sorties dans des fichiers texte pour comparer plus tard, par exemple docker inspect > inspect.json.
Conteneurs qui quittent immédiatement
Symptôme: docker run sort avec le code 0 ou un code non nul et le service ne reste pas actif.
Checklist:
- Inspecter code de sortie et raison:
docker inspect -f '{{.State.ExitCode}} {{.State.Error}}' <ctr>
- Afficher les derniers logs:
docker logs --tail=100 <ctr>
- Lancer l'image en interactif pour observer le cycle de vie:
docker run --rm -it <image> sh
- Confirmer CMD/ENTRYPOINT:
docker inspect -f '{{.Config.Entrypoint}} {{.Config.Cmd}}' <image>
Causes fréquentes et correctifs:
- Le processus s'est terminé normalement (exit 0). Ajoutez un processus au premier plan ou utilisez une vraie commande serveur. Pour débogage rapide:
docker run -it --entrypoint sh <image>
# ou le garder en vie temporairement
docker run -d --name debug <image> sh -c 'tail -f /dev/null'
- Mauvais ENTRYPOINT. Préférez un script d'entrée qui exécute le processus final pour que les signaux fonctionnent:
#!/bin/sh
set -e
exec "$@"
- Dépendances manquantes à l'exécution. Valider dans le conteneur:
ldd /path/to/binary || true
which node || which python || which nginx
Réseau et ports
Symptôme: le service ne répond pas sur le port attendu ou l'attache échoue avec "address already in use".
Checklist:
- Vérifier les mappages de ports:
docker ps --format 'table {{.Names}}\t{{.Ports}}'
- Chercher des conflits sur l'hôte:
# Linux/macOS
sudo lsof -i :8080 || sudo ss -lntp | grep ':8080'
- Confirmer l'écoute dans le conteneur:
docker exec -it <ctr> sh -c 'ss -lntp || netstat -lntp'
- Tester l'accessibilité:
# Depuis l'hôte
curl -v http://localhost:8080
# Depuis un autre conteneur sur le même réseau
docker run --rm --network <net> curlimages/curl:8.7.1 curl -sv http://<service>:<port>
Correctifs:
- Changer le port côté hôte:
-p 8081:8080quand 8080 est occupé. - Lier à
0.0.0.0dans le conteneur si l'app écoute127.0.0.1par défaut. - Valider le réseau de conteneur:
docker network inspect <net>et s'assurer que les services partagent le même réseau.
DNS et problèmes de proxy
Symptôme: les conteneurs ne résolvent pas les noms ou n'atteignent pas internet derrière un proxy.
Checklist:
- Vérifier le résolveur dans le conteneur:
cat /etc/resolv.conf
- Tester le DNS:
docker run --rm busybox:1.36 getent hosts example.com || nslookup example.com
- Cas proxy d'entreprise:
- Passer
HTTP_PROXY,HTTPS_PROXYetNO_PROXYaux builds et aux runs. - Pour les builds:
docker build --build-arg HTTP_PROXY=$HTTP_PROXY --build-arg HTTPS_PROXY=$HTTPS_PROXY .
- Surcharger le DNS si besoin:
docker run --dns 8.8.8.8 --dns 1.1.1.1 <image>
Correctifs:
- Configurer le DNS au niveau du démon seulement si nécessaire; préférer les flags par conteneur.
- Définir
NO_PROXYpour les noms internes et noms de service sur les réseaux définis par l'utilisateur.
Volumes et permissions
Symptôme: Permission denied lors d'écritures sur un bind mount ou un volume.
Checklist:
- Inspecter les montages:
docker inspect -f '{{json .Mounts}}' <ctr> | jq .
- Vérifier la propriété côté hôte:
ls -l /host/path
stat -c '%u:%g %n' /host/path # Linux
- Trouver l'UID/GID du processus conteneur:
docker exec -it <ctr> id
Correctifs:
- Aligner les UIDs:
chown -R 1000:1000 /host/pathpour correspondre à l'utilisateur de l'app, ou exécuter avec-u 1000:1000. - Utiliser un volume nommé pour éviter les soucis de permissions hôte pour les données d'app:
docker volume create appdata && docker run -v appdata:/var/lib/app ...
- Hôtes SELinux: ajouter
:Zou:zaux bind mounts pour re-libeller le contexte si approprié. - Valider Nginx et les statiques dans les stacks web:
docker exec -it <ctr> sh -c 'nginx -t && ls -l /usr/share/nginx/html'
Build et problèmes d'image
Échecs de build fréquents et builds lents.
Symptômes et correctifs:
- Cache périmé ou mauvais ordre de couches:
- Utiliser
.dockerignorepour réduire le contexte. - Placer
apt-get installetpackage.jsonplus tôt pour un meilleur cache. - Valider un rebuild propre:
docker build --no-cache -t app: test . - Échecs réseau pendant RUN:
- Réessayer avec une image de base incluant curl pour déboguer le réseau.
- Respecter
HTTP(S)_PROXYetNO_PROXYdans le Dockerfile viaARG/ENV. - No space left on device:
- Inspecter:
docker system df,docker builder du - Purger en sécurité:
docker image prune -f
docker builder prune -f
- Supprimer uniquement les images dangling inutiles; éviter la purge globale sur hôtes partagés.
- Images volumineuses:
- Utiliser des multi-stage builds pour ne copier que les artefacts finaux.
- Préférer alpine ou des images minimales compatibles.
Astuces Docker Compose
Déboguer des applications multi-services.
Commandes utiles:
docker compose ps
docker compose logs -f service
docker compose config
Disponibilité des services:
- Ajoutez des healthchecks et faites attendre les dépendants la readiness plutôt que l'ordre de démarrage.
Exemple de healthcheck et simple boucle d'attente:
services:
db:
image: postgres:16
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U postgres']
interval: 5s
timeout: 3s
retries: 10
api:
build: ./api
depends_on:
- db
environment:
DATABASE_URL: postgres://postgres@db:5432/app
command: sh -lc 'until pg_isready -h db -U postgres; do sleep 1; done; exec ./api'
Réseau:
- Assurez-vous que les services partagent le même réseau défini par l'utilisateur (par défaut avec Compose).
Cas limites Kubernetes
Quand les conteneurs tournent dans Kubernetes, mappez les symptômes du cluster au comportement du conteneur.
Checklist:
- Trouver le pod et les événements:
kubectl get pods -n <ns>
kubectl describe pod/<name> -n <ns>
- Logs:
kubectl logs <pod> -n <ns> --previous
Vérifier le tag d'image, l'authentification du registre et la pull policy.
Aligner readiness et liveness sur le vrai temps de démarrage et le port.
- Problèmes de pull d'image:
- Probes de santé:
Reproduction locale:
- Tirer la même image en local et exécuter avec env et commande similaires pour déboguer plus vite:
docker run --rm -e VAR=val <image>:<tag>
- Si CrashLoopBackOff, se concentrer d'abord sur les logs du conteneur et les arguments d'entrypoint.
Notes GitLab CI/CD
Patterns courants de runners Docker.
Docker-in-Docker (dind) pour construire des images:
image: docker:27
services:
- name: docker:27-dind
command: ['--mtu=1460']
variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_TLS_CERTDIR: ''
stages: [build]
build:
stage: build
script:
- docker info
- docker build -t registry.example.com/app:$CI_COMMIT_SHORT_SHA .
- docker push registry.example.com/app:$CI_COMMIT_SHORT_SHA
Astuces:
- Définir
DOCKER_TLS_CERTDIR=''si vous utilisez volontairement TCP en clair avec dind sur des runners de confiance. - Si la résolution de noms échoue dans les jobs, passer
HTTP(S)_PROXYetNO_PROXYet vérifier avecdocker run busybox getent hosts. - Pour les bind mounts dans le runner, alignez UID/GID ou utilisez un volume pour éviter les erreurs de permission.
Plan pilote local
Démarrez par un petit pilote mesurable que vous pouvez inspecter localement.
But du pilote: démarrer un simple service Nginx via Docker Compose, ajouter des healthchecks, répéter 3 scénarios d'échec et documenter les correctifs.
Périmètre (restez petit):
- Un fichier compose avec
nginx: alpineservant unindex.htmlstatique. - Healthcheck: GET
http://localhost:8080/retourne 200.
Étapes:
- Exécution de base:
docker compose up -d
curl -v http://localhost:8080/
- Ajouter un conflit de port délibéré:
- Démarrer un processus sur 8080, observer l'erreur compose et basculer sur 8081.
- Ajouter un mauvais montage en permission:
- Monter un dossier en lecture seule et confirmer 403 ou erreurs d'écriture; corriger la propriété ou utiliser un volume.
- Ajouter une panne DNS dans un job sidecar curl:
- Lancer un conteneur curl sur le même réseau pour tester le DNS externe; ajouter une option
--dnssi besoin.
- Capturer et stocker commandes et sorties dans un fichier
troubleshooting.mdau sein du dépôt.
Critères de succès:
- Les trois échecs reproduits et résolus localement.
- Healthcheck passant de manière cohérente.
- Liste claire de commandes et sorties attendues pour chaque scénario.
Conclusion
Vous disposez maintenant d'un flux pratique pour trier les problèmes Docker, lire les bons logs et appliquer des correctifs minimaux et sûrs. Commencez par l'état du service et les Docker logs, confirmez le réseau, puis vérifiez volumes, permissions et couches de build. Avec Docker Compose, appuyez-vous sur des healthchecks et de simples attentes plutôt que l'ordre de démarrage. Dans Kubernetes et en CI, ramenez toujours les symptômes aux fondamentaux du conteneur. Lancez un petit pilote local, mesurez les résultats et étendez l'approche service par service pour accélérer votre Docker recovery.