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 -h

- free -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 -a

- docker inspect <conteneur-ou-image>

- Lire les journaux en premier

- docker logs <conteneur> --since=10m -n 200

- docker events --since 10m

- Journaux du démon (Linux) : journalctl -u docker --since "10 min ago"

- Vérifier le réseau

- docker network ls

- docker 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 -l sur 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 .

</div>

## 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 exec le 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 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:8080 quand 8080 est utilisé.

- Binder sur 0.0.0.0 à l’intérieur du conteneur si l’application bind par défaut sur 127.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_PROXY et NO_PROXY aux 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_PROXY pour 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/hote pour 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 :Z ou :z aux 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 .dockerignore pour réduire le contexte (exclure node_modules , .git , *.log ).

- Placer les étapes apt-get install et package.json plus 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 curl pour déboguer le réseau.

- Respecter HTTP(S)_PROXY et NO_PROXY dans le Dockerfile via ARG / 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 alpine ou 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 imagePullSecrets et 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)_PROXY et NO_PROXY et vérifier avec docker 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:alpine servant un index.html statique.

- 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 --dns si nécessaire.

- Capturer et stocker commandes et sorties dans un fichier troubleshooting.md au 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.