Introduction
Quand Docker fonctionne, il se fait discret : un conteneur démarre, sert le trafic et s'arrête sur commande. Quand il tombe en panne, le message d'erreur peut ressembler à une énigme. Ce guide rassemble les erreurs de la CLI Docker les plus fréquemment rencontrées en développement et en production, explique ce que chaque message signifie réellement, et vous donne la correction exacte ainsi que la commande pour la vérifier.
Nous couvrons Docker pour Linux, macOS et Windows, y compris Docker Desktop et Docker Engine, avec une attention particulière à docker compose et aux échecs courants liés aux images, conteneurs, réseaux et volumes. Chaque section commence par le texte d'erreur que vous verrez, puis montre la cause, la correction et une vérification ultérieure pour confirmer que le problème a disparu.
Ceci n'est pas un manuel de référence. C'est un chemin de dépannage : observer d'abord, changer une chose, vérifier, puis passer à la suite. Vous pouvez l'utiliser pendant un incident ou comme liste de contrôle avant votre prochain déploiement.
1. Inventaire de l'environnement et des versions
Avant de corriger quoi que ce soit, connaissez votre version et votre contexte. De nombreuses erreurs sont spécifiques à une version : une option qui fonctionne dans Docker 23 peut ne pas exister dans Docker 20, et Docker Desktop se comporte différemment de Docker Engine sur Linux.
Commencez par un inventaire en lecture seule :
docker version
docker info
docker version affiche les versions du client et du serveur. Si la version du serveur est manquante, votre client ne peut pas atteindre le démon. docker info imprime le pilote de stockage, le pilote de journalisation, le répertoire racine et, surtout, le nombre de conteneurs en cours d'exécution et d'images. Il montre également des avertissements : pas de support de limite de swap, pas de cgroup v2, ou un réseau pont manquant.
Pour Docker Context, qui peut silencieusement cibler un démon distant ou rootless, listez les contextes :
docker context ls
Si vous voyez un contexte nommé remote-prod que vous avez oublié de quitter, chaque commande docker run tentera d'utiliser ce démon distant. Revenez avec docker context use default.
Commandes d'inventaire pratiques :
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
docker images | head -n 10
docker system df
La première affiche les conteneurs en cours d'exécution avec les noms, l'état et les ports ; la deuxième montre les images récemment construites ou récupérées ; la troisième montre l'utilisation du disque par les images, les conteneurs, les volumes et le cache de construction. docker system df est souvent le premier indice qu'une construction échoue parce que le disque est plein (erreur : no space left on device).
Pour un projet Compose :
docker compose ps
docker compose config
La commande config valide et imprime le fichier compose fusionné, montrant la substitution des variables d'environnement et les valeurs par défaut. Une erreur courante est de modifier docker-compose.yml mais d'exécuter docker compose dans un autre répertoire ; docker compose ps ne listera aucun conteneur, et vous pourriez penser que le service est en panne.
En règle générale : enregistrez la sortie de ces commandes avant de changer quoi que ce soit. Vous avez besoin d'une base de référence pour comparer.
2. Chemin de configuration sûr
Les erreurs de configuration sont la source la plus courante de défaillances de la CLI Docker. La correction consiste à modifier un fichier de configuration ou une variable d'environnement à la fois, puis à valider.
2.1 Configuration du démon Docker (daemon.json)
La plupart des paramètres du démon se trouvent dans /etc/docker/daemon.json sur Linux ou sous Settings > Docker Engine dans Docker Desktop. Une virgule manquante ou une mauvaise clé empêchera le démon de démarrer. Sur Linux, après modification, exécutez :
sudo dockerd --validate
Ceci vérifie la syntaxe sans démarrer le démon. Ensuite, redémarrez Docker :
sudo systemctl restart docker
Si le démon ne démarre pas, lisez le journal :
sudo journalctl -u docker --since "10 minutes ago" -f
Une erreur typique : failed to start daemon: error initializing graphdriver: /var/lib/docker contains several valid graphdrivers. Cela signifie que vous avez changé le pilote de stockage dans daemon.json mais que les données existantes utilisent un autre pilote. Le chemin sûr est de revenir sur le changement et de planifier une migration.
2.2 Fichiers Compose
Les fichiers Compose sont du YAML, et l'indentation et les champs de version comptent. Exécutez toujours :
docker compose config --quiet
Aucune sortie ne signifie que le fichier est valide. S'il y a une erreur, il imprime la ligne et la raison. --quiet est non destructif et rapide.
Erreurs courantes :
- Utiliser une correspondance pour
environmentcommeVAR: valueau lieu d'une liste. Compose v3 attend une liste :
environment:
- POSTGRES_USER=myuser
- POSTGRES_PASSWORD=mypass
- Oublier de mettre entre guillemets les chaînes avec des caractères spéciaux, par exemple
$dans les mots de passe. Un$VARnon cité tentera d'étendre l'environnement hôte. - Utiliser
version: "3.9"mais le plugin Compose installé ne prend en charge que jusqu'à 3.8. Supprimez complètement le champversionpour les versions récentes de Docker Compose ; il est facultatif et peut provoquer un avertissement.
2.3 Variables d'environnement dans la CLI
Lors du passage de variables à un conteneur, docker run -e ou --env-file doit utiliser key=value. Un espace de fin après une virgule dans --env-file cassera l'analyse. Préférez :
docker run --env-file ./config.env myapp
Et dans config.env, une variable par ligne, pas d'espaces autour de =.
3. Vérification et diagnostics
Après toute correction, vérifiez que le composant fonctionne comme prévu. Utilisez d'abord des commandes en lecture seule, puis les journaux, puis un shell interactif si nécessaire.
3.1 Vérifier l'état du conteneur
docker ps --filter "status=exited" --format "{{.Names}}\t{{.ExitCode}}"
Ceci liste les conteneurs arrêtés et leurs codes de sortie. Un code de sortie non nul indique souvent la raison. Ensuite, inspectez-en un :
docker inspect <conteneur> --format '{{.State.ExitCode}} {{.State.Error}} {{.State.OOMKilled}}'
Si OOMKilled est vrai, le conteneur a atteint une limite de mémoire. Vérifiez la limite avec docker inspect <conteneur> | grep -i memory, puis augmentez-la dans la commande d'exécution (--memory=2g) ou dans compose (mem_limit: 2g).
3.2 Lire les journaux
docker logs <conteneur> --tail 100 --timestamps
Utilisez --since 10m pour voir uniquement les entrées récentes. Si le conteneur redémarre rapidement, suivez avec docker logs -f <conteneur> pour attraper l'échec avant le prochain redémarrage (le conteneur peut être programmé pour redémarrer par une politique de redémarrage).
Pour un service Compose :
docker compose logs <service> --tail 200
3.3 Exécuter un shell de débogage interactif
Parfois, vous devez voir le système de fichiers ou tester une connexion réseau à l'intérieur du conteneur. Ne modifiez pas l'image ; exécutez un nouveau shell avec la même configuration :
docker run --rm -it --entrypoint sh <image>
Ceci démarre un conteneur frais à partir de l'image avec un point d'entrée remplacé. Ensuite, vous pouvez ls, cat des fichiers de configuration, ou curl un endpoint local.
Pour un conteneur en cours d'exécution, utilisez docker exec :
docker exec -it <conteneur> sh
Attention : toute modification que vous apportez dans une session exec n'est pas enregistrée dans l'image et sera perdue au redémarrage du conteneur. Utilisez ceci uniquement pour l'observation.
3.4 Diagnostics réseau
Pour tester la connectivité entre conteneurs, exécutez un petit conteneur Alpine avec ping ou curl :
docker run --rm --network <monreseau> alpine ping <nom-autre-conteneur>
Si le ping échoue, vérifiez que les deux conteneurs sont sur le même réseau : docker network inspect <monreseau> et regardez la carte Containers. Les noms ne sont résolubles que sur les réseaux définis par l'utilisateur, pas sur le pont par défaut.
4. Modes de défaillance et récupération
Voici les erreurs de la CLI Docker les plus courantes, leurs causes et les étapes de récupération corrigées.
4.1 Cannot connect to the Docker daemon at unix:///var/run/docker.sock
Cause : le démon Docker ne fonctionne pas, ou votre utilisateur n'a pas la permission d'accéder au socket.
Correction :
- Vérifiez si le démon fonctionne :
systemctl status dockersur Linux, ou ouvrez Docker Desktop sur macOS/Windows. - Sur Linux, si le démon fonctionne mais que vous obtenez une permission refusée, ajoutez votre utilisateur au groupe
docker:
sudo usermod -aG docker $USER
Déconnectez-vous et reconnectez-vous, ou exécutez newgrp docker pour rafraîchir l'appartenance au groupe sans vous déconnecter.
- Si vous utilisez Docker rootless, définissez la variable d'environnement
DOCKER_HOSTsur le socket utilisateur :export DOCKER_HOST=unix:///run/user/1000/docker.sock.
Vérifiez : docker info doit retourner sans erreur.
4.2 Accès refusé au pull / le dépôt n'existe pas
Exemples d'erreur : pull access denied for myimage, repository does not exist or may require 'docker login'.
Correction :
- Pour les images publiques, assurez-vous que le nom est correct :
docker pull alpine(pasAlpineoualpine:latestsi le tag est incorrect). - Pour les registres privés, connectez-vous d'abord :
docker login registry.example.com
Puis récupérez avec le chemin complet : docker pull registry.example.com/team/myimage:tag.
- Si vous utilisez Docker Desktop et que le registre est sur votre hôte (par exemple
localhost:5000), vous devrez peut-être ajouter une entrée de registre non sécurisé dans les paramètres du démon ou configurer un certificat TLS.
Vérifiez : docker pull réussit et l'image apparaît dans docker images.
4.3 Port déjà utilisé
Erreur : docker: Error response from daemon: driver failed programming external connectivity on endpoint ... Bind for 0.0.0.0:8080 failed: port is already allocated.
Correction :
- Trouvez ce qui utilise le port sur l'hôte :
sudo ss -ltnp | grep 8080ousudo lsof -i :8080. - Arrêtez le processus en conflit (si possible) ou changez le port hôte :
docker run -p 8081:8080ou dans compose :
ports:
- "8081:8080"
- Si le conflit est avec un autre conteneur, supprimez ou arrêtez ce conteneur, ou utilisez un port dynamique :
docker run -P(mappe le port du conteneur à un port hôte élevé aléatoire).
Vérifiez : docker ps montre votre conteneur avec le port hôte choisi, et un curl http://localhost:8081 retourne la réponse attendue.
4.4 Le conteneur se termine immédiatement
Votre commande docker run a démarré, mais docker ps ne montre aucun conteneur. docker ps -a montre qu'il s'est terminé avec le code 0 ou 1.
Causes courantes :
- Le processus principal du conteneur s'est terminé. Par exemple, un script ponctuel a besoin d'un processus de premier plan pour rester en vie.
- La commande est manquante. Si vous exécutez
docker run myimageet que l'image n'a pas deCMD, le conteneur se termine. - L'application plante en raison de variables d'environnement, de configuration ou de dépendances manquantes.
Correction :
- Exécutez toujours avec
-itpour les tests interactifs :docker run -it myimage shet démarrez manuellement l'application pour voir les erreurs. - Vérifiez les journaux :
docker logs <conteneur>. - Pour un service qui doit rester en fonctionnement, assurez-vous que la commande est un processus de longue durée comme
nginx -g 'daemon off;'outail -f /dev/nullpour les tests. - Dans compose, définissez
restart: unless-stoppedpour redémarrer automatiquement après les plantages, mais vérifiez toujours les journaux pour la cause racine.
4.5 Fichier ou répertoire introuvable
Erreurs : no such file or directory lors du montage d'un volume, ou à l'intérieur du conteneur, le fichier attendu est manquant.
Cause : le chemin hôte n'existe pas, ou le chemin à l'intérieur du conteneur est incorrect, ou le fichier n'est pas copié car il est dans .dockerignore.
Correction :
- Pour les montages bind, assurez-vous que le répertoire hôte existe avant
docker run. Docker le créera en tant que root s'il est manquant, ce qui entraînera des problèmes de permission. Créez-le vous-même :mkdir -p ./data. - Pour COPY dans un Dockerfile, vérifiez que
.dockerignoren'exclut pas le fichier. - Pour les volumes, vérifiez si le volume a des données :
docker volume inspect monvolumeet regardez le point de montage. Vous pouvez copier des données dans le volume en exécutant un conteneur jetable avec le volume monté. - À l'intérieur du conteneur, utilisez
lsetpwdpour vérifier le répertoire de travail. Le répertoire de travail par défaut est/sauf s'il est défini avecWORKDIRdans le Dockerfile ou-wsur la CLI.
5. Pièges courants et comment s'en remettre
Même les utilisateurs Docker expérimentés rencontrent ces surprises.
5.1 Modifier des fichiers à l'intérieur d'un conteneur sans volume
Vous docker exec dans un conteneur, modifiez un fichier de configuration, redémarrez le conteneur, et le changement a disparu. Pourquoi ? Le système de fichiers du conteneur est éphémère et ne persiste pas par défaut.
À éviter : ne faites jamais de modifications manuelles dans un conteneur en cours d'exécution que vous attendez de survivre. Au lieu de cela, soit :
- Intégrez le changement dans l'image via le Dockerfile, soit
- Montez un volume ou un bind mount pour ce fichier/répertoire, et modifiez le fichier sur l'hôte.
Si vous avez déjà fait un changement d'urgence et qu'il doit survivre jusqu'au prochain déploiement, validez le conteneur dans une image temporaire :
docker commit <conteneur> myapp:hotfix
Mais traitez ceci comme un palliatif, pas comme un flux de travail. L'image manque du contexte de construction et de la documentation.
5.2 Utiliser le tag latest en production
docker pull myapp:latest peut obtenir une version différente demain, et le déploiement casse.
Récupération : épinglez toujours les versions dans les fichiers compose et CI/CD. Utilisez des tags spécifiques comme myapp:1.2.3 ou un digest. Si vous avez utilisé latest dans un déploiement en cours, vous pouvez inspecter l'image exacte avec docker inspect <conteneur> --format '{{.Image}}', puis trouver le digest et recréer le conteneur avec ce digest.
5.3 Oublier de nettoyer les ressources
Avec le temps, les images orphelines, les conteneurs arrêtés, les réseaux inutilisés et les volumes s'accumulent et remplissent le disque.
Correction : planifiez un nettoyage régulier. Exécutez ces commandes manuellement :
docker container prune # supprimer les conteneurs arrêtés
docker image prune # supprimer les images orphelines
docker network prune # supprimer les réseaux inutilisés
docker volume prune # supprimer les volumes inutilisés
Ou utilisez docker system prune -a pour supprimer toutes les ressources inutilisées, mais soyez prudent : cela supprime tous les conteneurs arrêtés, les réseaux inutilisés et les images non utilisées par un conteneur. Il ne supprime pas les volumes nommés par défaut ; ajoutez --volumes pour le faire. C'est une opération destructive ; ne l'exécutez que lorsque vous comprenez l'impact.
5.4 Ignorer les contrôles de santé
Un conteneur peut être "en cours d'exécution" mais pas prêt à servir les requêtes. L'instruction HEALTHCHECK de Docker dans le Dockerfile ou healthcheck dans compose peut marquer un conteneur comme malsain.
Récupération : ajoutez un contrôle de santé. Exemple pour un service web :
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 10s
timeout: 5s
retries: 3
start_period: 30s
Ensuite, utilisez docker inspect --format '{{.State.Health.Status}}' <conteneur> pour voir healthy, unhealthy ou starting. Dans compose, docker compose ps montre l'état de santé.
5.5 Ne pas utiliser de politique de redémarrage en production
Si un conteneur meurt et que rien ne le redémarre, votre service est en panne jusqu'à ce que quelqu'un intervienne manuellement.
Ajoutez une politique de redémarrage :
docker run --restart unless-stopped myapp
Ou dans compose :
restart: unless-stopped
unless-stopped redémarre le conteneur sauf si vous l'avez explicitement arrêté. always redémarre également après le redémarrage du démon, mais unless-stopped est généralement plus sûr car il respecte la maintenance manuelle.
6. Liste de contrôle opérationnelle
Utilisez cette liste avant et après tout changement Docker dans un environnement partagé.
Avant le changement
- [ ] Exécutez
docker context lset confirmez que vous ciblez le bon démon (par défaut, pas une production distante). - [ ] Enregistrez l'état actuel :
docker ps,docker images,docker system df,docker compose ps(le cas échéant). Enregistrez la sortie dans un fichier avec horodatage. - [ ] Identifiez la ressource exacte que vous modifierez : image, conteneur, réseau, volume ou fichier de configuration.
- [ ] Déterminez le rayon d'impact : s'agit-il d'un seul conteneur ou d'une pile entière ? Qu'est-ce qui en dépend ?
- [ ] Préparez un chemin de retour en arrière : pouvez-vous annuler le changement de configuration, redéployer l'ancien tag d'image ou restaurer un instantané de volume ?
- [ ] Pour les changements de fichier de configuration, validez d'abord la syntaxe :
docker compose config --quietoudockerd --validate.
Après le changement
- [ ] Exécutez la commande de vérification qui prouve que la correction a fonctionné, par exemple
curl http://localhost:8080/healthoudocker logs <conteneur> --tail 50ne montre aucune erreur. - [ ] Vérifiez les services dépendants : se connectent-ils toujours ? Le réseau est-il intact ?
docker network inspectmontre les conteneurs attendus. - [ ] Surveillez pendant quelques minutes :
docker stats <conteneur>montre le CPU et la mémoire,docker eventsmontre les changements de cycle de vie. - [ ] Mettez à jour le runbook ou le document d'incident avec l'erreur, la cause, la correction et la vérification.
- [ ] Planifiez un examen si la correction est temporaire : définissez un rappel pour revisiter le problème dans, par exemple, une semaine ou avant la prochaine version.
Responsable unique : dans un contexte d'équipe, attribuez une personne (par exemple l'ingénieur de garde ou le développeur qui a fait le changement) comme responsable de compléter la liste de contrôle et de documenter le résultat. Pour les tâches opérationnelles récurrentes, faites tourner cette responsabilité chaque semaine.
Conclusion
Les erreurs de la CLI Docker sont généralement causées par un petit ensemble de problèmes récurrents : connectivité du démon, échecs de récupération d'image, conflits de ports, conteneurs qui se terminent et mauvaises configurations de fichiers ou de volumes. Le chemin de récupération est le même à chaque fois : observer l'état, isoler le composant défaillant, apporter une modification chirurgicale et vérifier avec une commande spécifique.
Gardez ce guide à portée de main comme référence pour la prochaine erreur que vous verrez. Commencez par docker version et docker info, puis passez à la section d'erreur correspondante. Après la correction, exécutez la commande de vérification et enregistrez ce que vous avez fait. Cela transforme un incident en leçon.
Pour approfondir, explorez la documentation officielle de Docker sur les commandes CLI, la configuration du démon et les spécifications Compose. Plus vous pratiquez la boucle observer-changer-vérifier, plus vite vous résoudrez les futurs problèmes Docker.