Ce guide montre comment dépanner Docker avec des commandes concrètes, de courtes listes de contrôle et de petits flux de récupération. Il s’adresse aux développeurs, consultants DevOps et équipes de start‑up qui ont besoin de correctifs rapides et sûrs. Vous apprendrez un flux reproductible, verrez les patterns d’échec courants et appliquerez des exemples pratiques qui fonctionnent sur hôtes Linux et macOS, ainsi qu’à l’intérieur de Docker Compose et Kubernetes. Objectif : rendre les problèmes faciles à reproduire, mesurer et résoudre localement avant un déploiement plus large.
Vue d’ensemble du workflow
Utilisez ce flux reproductible pour la plupart des problèmes Docker :
- Vérifier les bases
- S’assurer que Docker tourne :
- Linux :
systemctl status docker - Tous :
docker info - Confirmer que le disque et la mémoire ne sont pas saturés :
df -hfree -m(Linux)docker system df
- Reproduire et capturer le contexte
- Noter la commande exacte, le fichier compose, le tag d’image et le message d’erreur.
- Conserver un cas de reproduction minimal si possible.
- Inspecter l’état du conteneur et de l’image
docker ps -adocker inspect <conteneur-ou-image>
- Lire les journaux en premier
docker logs <conteneur> --since=10m -n 200docker events --since 10m- Journaux du démon (Linux) :
journalctl -u docker --since "10 min ago"
- Vérifier le réseau
docker network lsdocker network inspect <réseau>- 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 les volumes et les permissions
docker inspect -f '{{.Mounts}}' <ctr>ls -lsur les chemins hôtes ; identifier les décalages UID/GID
- Vérifier la construction et le cache
docker build . --no-cache(pour valider une vraie reconstruction)docker history <image>
- Vérifier la pression sur les ressources
docker stats(vue en direct)ulimit -a; rechercher les OOM (Out Of Memory) kills dans les logs
- Corriger, retester et documenter brièvement
- Appliquer le plus petit correctif viable.
- Reconstruire/recréer uniquement les services affectés.
- Nettoyer prudemment (optionnel)
- Lister avant de purger :
docker system df - Purge ciblée :
docker image prune -f,docker builder prune -f - Éviter les purges globales destructives sur les hôtes partagés.
Journaux et diagnostics
Commencez par les journaux et un instantané rapide de l’état.
Commandes utilisées fréquemment :
- Journaux de conteneur :
docker logs <ctr>
docker logs -f --since=15m <ctr>
- Journaux 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 de commandes dans des fichiers texte pour les différencier plus tard, par exemple docker inspect > inspect.json.
Conteneurs qui s’arrêtent immédiatement
Symptôme : docker run se termine avec le code 0 ou un code non‑zéro, et le service ne reste pas en vie.
Liste de contrôle :
- Inspecter le code de sortie et la raison :
docker inspect -f '{{.State.ExitCode}} {{.State.Error}}' <ctr>
- Afficher les derniers logs :
docker logs --tail=100 <ctr>
- Lancer l’image en interactif pour voir le cycle de vie du processus :
docker run --rm -it <image> sh
- Confirmer CMD/ENTRYPOINT :
docker inspect -f '{{.Config.Entrypoint}} {{.Config.Cmd}}' <image>
Causes courantes et correctifs :
- Processus terminé normalement (exit 0). Ajoutez un processus en avant‑plan ou utilisez une commande serveur appropriée. Pour déboguer rapidement :
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
execle processus final pour que les signaux fonctionnent :
#!/bin/sh
set -e
exec "$@"
- Dépendances manquantes à l’exécution. Validez à l’intérieur du conteneur :
ldd /chemin/vers/binaire || true
which node || which python || which nginx
- Code de sortie 125 signifie souvent que Docker ne peut pas tirer l’image. Lancez
docker pull <image>manuellement pour voir l’erreur sous‑jacente.
Réseau et ports
Symptôme : le service ne répond pas sur le port attendu, ou le bind échoue avec "address already in use\).
Liste de contrôle :
- Vérifier les mappings de ports :
docker ps --format 'table {{.Names}}\t{{.Ports}}'
- Vérifier les conflits de ports sur l’hôte :
# Linux/macOS
sudo lsof -i :8080 || sudo ss -lntp | grep ':8080'
- Confirmer que le service écoute à l’intérieur du conteneur :
docker exec -it <ctr> sh -c 'ss -lntp || netstat -lntp'
- Tester la joignabilité :
# 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 mapping de port hôte :
-p 8081:8080quand 8080 est utilisé. - Binder sur
0.0.0.0à l’intérieur du conteneur si l’application bind par défaut sur127.0.0.1(ex.CMD ["python", "-m", "http.server", "8080", "--bind", "0.0.0.0\])`). - Valider le réseau du conteneur :
docker network inspect <net>et s’assurer que les deux services partagent le même réseau.
DNS et proxy
Symptôme : les conteneurs ne résolvent pas les noms ou n’atteignent pas Internet derrière un proxy.
Liste de contrôle :
- Vérifier le résolveur à l’intérieur du 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 :
- Transmettre
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 .
- Remplacer le DNS si nécessaire :
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 ; privilégier les drapeaux par conteneur.
- Définir
NO_PROXYpour les noms d’hôtes internes et les noms de services sur les réseaux définis par l’utilisateur.
Volumes et permissions
Symptôme : "Permission denied" lors de l’écriture sur un bind mount ou un volume.
Liste de contrôle :
- Inspecter les montages :
docker inspect -f '{{json .Mounts}}' <ctr> | jq .
- Vérifier la propriété du chemin hôte :
ls -l /chemin/hote
stat -c '%u:%g %n' /chemin/hote # Linux
- Trouver l’UID/GID du processus conteneur :
docker exec -it <ctr> id
Correctifs :
- Aligner les UIDs :
chown -R 1000:1000 /chemin/hotepour correspondre à l’utilisateur de l’application, ou lancer avec-u 1000:1000. - Utiliser un volume nommé pour éviter les problèmes de permissions hôtes sur les données d’application :
docker volume create appdata && docker run -v appdata:/var/lib/app ...
- Hôtes SELinux (Security-Enhanced Linux) : Linux avec sécurité renforcée : ajouter
:Zou:zaux bind mounts pour réétiqueter le contexte quand c’est approprié. - Valider les permissions Nginx et du contenu statique dans les stacks web :
docker exec -it <ctr> sh -c 'nginx -t && ls -l /usr/share/nginx/html'
Construction et images
Échecs de build courants et builds lents.
- Cache obsolète ou mauvais ordonnancement des couches :
- Utiliser
.dockerignorepour réduire le contexte (exclurenode_modules,.git,*.log). - Placer les étapes
apt-get installetpackage.jsonplus tôt pour un meilleur cache. - Valider une reconstruction propre :
docker build --no-cache -t app:test . - Échecs réseau pendant RUN :
- Réessayer avec une image de base incluant
curlpour 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 prudemment :
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 builds multi‑étape pour ne copier que les artefacts finaux.
- Préférer
alpineou des images minimales spécifiques à la distribution quand c’est compatible.
Astuces Docker Compose
Déboguer des applications multi‑services.
Commandes utiles :
docker compose ps
docker compose logs -f service
docker compose config
Prêtivité des services :
- Ajouter des healthchecks et faire attendre les services dépendants la disponibilité réelle plutôt que l’ordre de démarrage.
Exemple de healthcheck et boucle d’attente simple :
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 :
- S’assurer que les services partagent le même réseau défini par l’utilisateur (par défaut pour Compose).
Cas limites Kubernetes
Quand les conteneurs tournent dans Kubernetes (Kubernetes), ramener les symptômes du cluster au comportement du conteneur.
Liste de contrôle :
- 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.
- S’assurer que les probes readiness et liveness correspondent au vrai temps de démarrage et au port du conteneur.
Problèmes de pull d’image :
- Vérifier
imagePullSecretset que le registre est joignable depuis les nœuds du cluster.
Probes de santé :
- Exemple de readiness probe pour un service HTTP sur le port 8080 :
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
Reproduction locale :
- Tirer la même image localement et la lancer avec un env et une 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’entrée.
Notes GitLab CI/CD
Patterns courants de runner 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
Conseils :
- Mettre
DOCKER_TLS_CERTDIR=''quand vous utilisez intentionnellement du TCP clair avec dind dans des runners de confiance. - Si la résolution de noms échoue dans les jobs, transmettre
HTTP(S)_PROXYetNO_PROXYet vérifier avecdocker run busybox getent hosts. - Pour les bind mounts dans le runner, aligner UID/GID ou utiliser un volume pour éviter les erreurs de permission.
Plan pilote local
Commencez par un petit pilote mesurable que vous pouvez inspecter localement.
Objectif du pilote : monter un service Nginx simple via Docker Compose, ajouter des healthchecks, répéter trois scénarios d’échec et documenter les correctifs.
Périmètre (garder petit) :
- Un fichier compose avec
nginx:alpineservant unindex.htmlstatique. - Healthcheck :
GET http://localhost:8080/renvoie 200.
Étapes :
- Exécution de base :
docker compose up -d
curl -v http://localhost:8080/
- Ajouter un conflit de port délibéré :
- Lancer un processus sur 8080 (ex.
python -m http.server 8080), observer l’erreur compose et basculer sur 8081.
- Ajouter une permission de mount incorrecte :
- Monter un répertoire en lecture seule et confirmer l’erreur 403 ou d’écriture ; corriger la propriété ou utiliser un volume.
- Ajouter un échec DNS dans un job sidecar curl :
- Lancer un conteneur curl sur le même réseau pour tester le DNS externe ; ajouter l’override
--dnssi nécessaire.
- Capturer et stocker commandes et sorties dans un fichier
troubleshooting.mdau dépôt.
Critères de succès :
- Les trois échecs reproduits et résolus localement.
- Healthcheck passe de façon constante.
- Liste claire des 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 journaux et appliquer des correctifs sûrs et minimaux. Commencez par l’état du service et les logs, confirmez le réseau, puis vérifiez volumes, permissions et couches de build. Pour Compose, fiez‑vous aux healthchecks et aux boucles d’attente simples plutôt qu’à l’ordre de démarrage. Dans Kubernetes et CI, ramenez les symptômes aux mêmes fondamentaux du conteneur. Lancez un petit pilote local, mesurez les résultats et étendez l’approche service par service.