Intro
Les erreurs Docker peuvent sembler opaques, mais la plupart reviennent à un petit nombre de causes répétitives. Ce guide relie les erreurs les plus fréquentes à leurs causes racines, propose un flux de diagnostic pas à pas et présente des correctifs modernes, sûrs et vérifiables localement avant déploiement.
Pour qui :
- Développeurs qui livrent des services en conteneurs
- Ingénieurs DevOps qui standardisent la réponse aux incidents
- Équipes de startup qui construisent des pipelines de livraison fiables
Ce que vous obtiendrez :
- Un workflow reproductible pour diagnostiquer vite et sans risque
- Des correctifs pratiques pour les problèmes de build, d’exécution, de réseau, de volumes et de registre
- Un petit pilote local pour stabiliser les améliorations avant de les étendre
Aperçu du workflow
Utilisez ce flux pour couper le bruit et éviter le rework :
- Reproduire exactement
- Capturez la commande complète et les versions :
docker --versiondocker compose versiondocker info(masquez les secrets)docker buildx versiondocker context ls- Relancez avec des journaux complets :
docker build --progress=plain .docker run --rm -it IMAGE[:TAG] COMMANDdocker compose up --buildpuisdocker compose logs -f
- Lire tout le message d’erreur
- Beaucoup d’erreurs Docker affichent un court résumé, la vraie cause se trouvant quelques lignes plus haut. Faites défiler et capturez la première ligne en échec.
- Réduire le scénario
- Créez un Dockerfile de repro minimal et isolez l’étape fautive avec un seul
COPYouRUN. - Remplacez votre app par une base connue et saine (ex.
alpine,nginx:alpine) pour différencier problème infra vs applicatif.
- Comparer la configuration
- Comparez tags, plateformes et montages qui fonctionnent vs échouent.
- Inspectez le
Dockerfileétape par étape; vérifiez la sortie dedocker compose config. - Confirmez le contexte de build et tout override.
- Appliquer le plus petit correctif sûr
- Préférez les changements de configuration (chemins, permissions, plateforme) avant les modifications de code.
- Vérifier localement sur une base propre
- Optionnellement nettoyer les ressources inutilisées :
docker system dfpuisdocker system prune -f(attention : supprime les ressources non utilisées) - Rebuilder :
docker build --no-cache . - Exécuter :
docker run --rm IMAGE[:TAG]
Erreurs de build courantes
1) COPY failed: file not found in build context
Symptômes :
COPY failed: file not found in build context or excluded by .dockerignore
Pourquoi cela arrive :
- Le fichier est hors du contexte de build (le chemin passé à
docker build). .dockerignoreexclut le fichier ou son répertoire parent.
Comment diagnostiquer :
- Confirmez le contexte :
docker build -f app/Dockerfile ./appvsdocker build -f app/Dockerfile . - Listez les fichiers vus par Docker :
tar -cz . | tar -tz | head(à exécuter dans le répertoire de contexte visé) - Inspectez les motifs
.dockerignorequi pourraient exclure des fichiers nécessaires.
Correctif :
- Construisez depuis le bon répertoire et ajustez les chemins.
- Mettez à jour
.dockerignorepour conserver les fichiers requis.
Exemple :
# Faux : build depuis la racine du dépôt alors que le Dockerfile suppose le contexte ./app
docker build -t myapp -f app/Dockerfile .
# Correct : passer ./app comme contexte de build
docker build -t myapp -f app/Dockerfile ./app
2) exec format error (incompatibilité d’architecture)
Symptômes :
standard_init_linux.go:... exec format error- L’image fonctionne sur une machine mais pas sur une autre (ex. portable ARM vs serveur AMD64).
Pourquoi cela arrive :
- La plateforme de l’image ne correspond pas à l’hôte ou au nœud cible.
Comment diagnostiquer :
- Vérifiez l’archi de l’hôte :
uname -m - Vérifiez les plateformes de l’image :
docker buildx imagetools inspect IMAGE:TAG
Correctif :
- Construisez ou tirez pour la bonne plateforme avec BuildKit/Buildx.
Exemples :
# Forcer la plateforme au build ou à l’exécution
docker buildx build --platform linux/amd64 -t myapp:amd64 .
docker run --rm --platform linux/amd64 myapp:amd64
# Construire une image multi-arch et pousser une liste de manifestes
docker buildx create --use --name multi
docker buildx build --platform linux/amd64,linux/arm64 -t registry.example.com/myorg/myapp:1.0 --push .
3) no space left on device
Symptômes :
- Les builds échouent lors de l’écriture des couches ou pendant l’installation de paquets.
Pourquoi cela arrive :
- Les images, couches et caches de build Docker ont saturé le disque.
Comment diagnostiquer :
docker system df- Sous Linux :
df -hetdu -sh /var/lib/docker/*(chemin variable selon l’installation)
Correctif :
# Libérer de l’espace (à utiliser avec précaution)
docker system prune -f
docker image prune -a -f
docker volume prune -f
# Spécifiquement pour le cache de build
docker builder prune -f
Conseils pratiques :
- Utilisez des builds multi-étapes pour éviter d’embarquer les outils de build dans l’image finale.
- Nettoyez les caches de paquets dans la même couche
RUN(ex.apt-get clean && rm -rf /var/lib/apt/lists/*). - Utilisez les montages de cache BuildKit pour accélérer les installations sans gonfler les couches :
# Exemple pour pip
RUN --mount=type=cache,target=/root/.cache/pip \
pip install --no-cache-dir -r requirements.txt
4) RUN échoue à cause du shell ou des fins de ligne
Symptômes :
/bin/sh: 1: script.sh: not foundexec user process caused: no such file or directory
Pourquoi cela arrive :
- Fins de ligne Windows CRLF, bit exécutable manquant, mauvais shebang, ou usage de
bashalors que l’image ne contient quesh.
Correctif :
# Normaliser les fins de ligne au commit
git config core.autocrlf input
# Convertir les fichiers si nécessaire
dos2unix script.sh
# Assurer les permissions et un shebang valide
chmod +x script.sh
sed -n '1p' script.sh # doit commencer par #!/bin/sh ou #!/usr/bin/env bash
Si vous avez besoin des fonctionnalités Bash, définissez explicitement le shell dans le Dockerfile :
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
5) Confusion liée au cache de build
Symptômes :
- Anciennes dépendances persistantes; les changements ne s’appliquent pas comme prévu.
Correctif et vérification :
# Afficher la sortie détaillée pour comprendre les décisions de cache
docker build --progress=plain .
# Forcer des couches fraîches quand nécessaire
docker build --no-cache --pull .
Bonne pratique : placez les étapes les plus stables (dépendances système) avant la copie du code applicatif pour maximiser la réutilisation du cache.
Erreurs d’exécution et Compose
1) Port déjà alloué
Symptômes :
Error starting userland proxy: listen tcp 0.0.0.0:80: bind: address already in use
Comment diagnostiquer :
docker ps --format 'table {{.ID}}\t{{.Image}}\t{{.Ports}}'lsof -i :80(Linux/macOS) ouGet-NetTCPConnection -LocalPort 80(PowerShell)
Correctif :
# Remapper le port hôte
docker run -p 8080:80 nginx:alpine
Exemple Compose :
services:
web:
image: nginx:alpine
ports:
- "8080:80"
2) exec user process caused: no such file or directory
Symptômes :
- Le conteneur se termine immédiatement au démarrage.
Pourquoi cela arrive :
- L’ENTRYPOINT/CMD pointe vers un fichier manquant ou avec des fins de ligne CRLF.
Comment diagnostiquer et corriger :
# Inspecter les fichiers à l’intérieur de l’image
docker run --rm -it --entrypoint sh myapp:tag -c 'ls -l /app && file /app/entrypoint.sh && cat -A /app/entrypoint.sh | head'
# Puis normaliser les fins de ligne et les permissions comme dans les correctifs de build
Assurez-vous que les chemins ENTRYPOINT/CMD sont absolus et que les fichiers existent dans l’étape finale des builds multi-étapes.
3) OCI runtime create failed: permission denied
Pourquoi cela arrive :
- Permissions de bind mount, limites de Docker rootless, ou labels SELinux sous Linux.
Correctifs :
# Aligner l’utilisateur du conteneur avec les fichiers de l’hôte
docker run -u $(id -u):$(id -g) -v "$PWD/data":/data myapp:tag
# Sur un hôte SELinux, étiqueter les bind mounts (:z partagé, :Z privé)
docker run -v "$PWD/data":/data:Z myapp:tag
Si vous avez besoin de root dans le conteneur avec Docker rootless, reconsidérez cette exigence ou basculez vers un environnement privilégié seulement si justifié.
4) Réseau introuvable dans Compose
Symptômes :
network mynet declared as external, but could not be found
Correctif :
# Créer explicitement le réseau
docker network create mynet
# Ou laisser Compose le gérer en supprimant external: true
Vérifiez avec docker network ls et docker compose config.
5) Le conteneur n’arrive pas à joindre un service hôte via localhost
Symptômes :
- L’application dans le conteneur n’atteint pas un service de l’hôte via
localhost.
Correctif :
- Utilisez
host.docker.internal(macOS/Windows, et Linux Desktop récents) ou l’IP du pont Docker (souvent172.17.0.1sous Linux).
curl http://host.docker.internal:3000
Réseau et DNS
1) Temporary failure in name resolution
Symptômes :
- Les résolutions DNS échouent à l’intérieur du conteneur.
Pourquoi cela arrive :
- DNS de l’hôte/resolveur atypique, proxy d’entreprise, ou sortie vers Internet bloquée.
Comment diagnostiquer et corriger :
# Tester le DNS dans un conteneur éphémère
docker run --rm busybox nslookup google.com || true
# Surcharger le DNS par conteneur (test rapide)
docker run --rm --dns 8.8.8.8 busybox nslookup google.com
DNS au niveau du daemon (puis redémarrer Docker) :
{
"dns": ["8.8.8.8", "1.1.1.1"]
}
Derrière un proxy : définissez HTTP_PROXY, HTTPS_PROXY et NO_PROXY pour le build et l’exécution. Pour les builds :
docker build --build-arg HTTP_PROXY=http://proxy:3128 --build-arg HTTPS_PROXY=http://proxy:3128 .
2) Cannot pull: lookup registry-1.docker.io: no such host
Correctif :
- Appliquez les mêmes étapes DNS ci‑dessus.
- Vérifiez la connectivité de l’hôte :
curl -I https://registry-1.docker.io. - Envisagez un miroir de registre via
"registry-mirrors"dansdaemon.jsonsi votre réseau est restrictif.
3) certificate signed by unknown authority (CA d’entreprise)
Symptômes :
- Les pulls/builds vers des registres internes échouent la vérification TLS.
Correctif dans l’image (confiance au runtime) :
COPY corp-ca.crt /usr/local/share/ca-certificates/
RUN update-ca-certificates
Pour le trust store du daemon Docker, installez votre CA selon le guide de votre OS puis redémarrez Docker.
Volumes et permissions
1) Permission denied sur les bind mounts
Symptômes :
- L’application ne peut pas lire/écrire les fichiers montés.
Pourquoi cela arrive :
- Décalage UID/GID entre l’hôte et l’utilisateur du conteneur; labels SELinux sous Linux.
Comment diagnostiquer :
- Sur l’hôte :
stat -c "%u:%g" data/ - Dans le conteneur :
id,ls -l /data
Correctifs :
# Exécuter avec l’UID/GID correspondant
docker run -u $(id -u):$(id -g) -v "$PWD/data":/data myapp:tag
# Préférer les volumes nommés pour des écritures plus portables
docker volume create appdata
docker run -v appdata:/data myapp:tag
Exemple Compose (avec SELinux) :
volumes:
data: {}
services:
app:
image: myapp:tag
user: "${UID:-1000}:${GID:-1000}"
volumes:
- data:/data
- "${PWD}/data:/data-host:Z"
2) Partage de fichiers non activé (macOS/Windows)
Symptômes :
- Le bind mount apparaît vide ou échoue.
Correctif :
- Activez le partage de fichiers pour le lecteur/dossier dans les réglages Docker Desktop. Sous Windows avec WSL 2, privilégiez un montage depuis le système de fichiers Linux (par ex. dans
~/project) pour de meilleures performances.
Images et registre
1) pull access denied, repository does not exist or may require authorization
Correctif :
# Vérifier le nom d’image et le tag
docker pull registry.example.com/team/app:1.2.3
# S’authentifier auprès du registre
docker login registry.example.com
2) manifest unknown or not found
Pourquoi cela arrive :
- Le tag n’existe pas ou le manifeste pour votre plateforme manque.
Correctif :
# Inspecter les plateformes disponibles
docker buildx imagetools inspect IMAGE:TAG
# Tirer pour une plateforme spécifique si disponible
docker pull --platform linux/amd64 IMAGE:TAG
3) Rate limit exceeded (registres publics)
Correctif :
- Authentifiez‑vous pour augmenter les limites.
- Utilisez un miroir privé ou un cache de registre.
- Regroupez et figez les images de base pour réduire le churn.
Performances et ressources
1) OOMKilled ou pression mémoire
Symptômes :
- Le conteneur s’arrête;
docker inspectindique"OOMKilled": true.
Comment diagnostiquer :
docker statspour observer l’usage mémoire en temps réel.- Vérifiez les journaux applicatifs pour repérer des pics.
Correctif :
# Définir des limites à l’exécution
docker run --memory=512m --memory-swap=512m myapp:tag
Compose (s’applique aux implémentations Compose non‑Swarm) :
services:
app:
image: myapp:tag
mem_limit: 512m
cpus: 1.0
Ajustez l’empreinte mémoire de l’application et n’augmentez les limites qu’en cas de besoin.
2) Builds lents dus à des ratés de cache
Correctif :
- Réordonnez le Dockerfile : installez les dépendances OS avant de copier le code qui change souvent.
- Utilisez des builds multi‑étapes pour garder des images finales légères.
- Employez les montages de cache BuildKit pour les caches de langages/paquets (pip, npm, go, cargo).
- Figez les versions de dépendances pour rendre les hits de cache prévisibles.
Exemple (Python) :
FROM python:3.12-slim AS base
WORKDIR /app
COPY requirements.txt .
RUN --mount=type=cache,target=/root/.cache/pip \
pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]
Plan pilote local
Objectif
- Prouver que les erreurs courantes sont détectées et corrigées rapidement sur un seul service.
Périmètre
- Un Dockerfile (ex. service Nginx ou Python minimal).
- Un compose.yaml exposant un port HTTP et un répertoire de données inscriptible.
Étapes
- Créer un mini‑service
FROM nginx:alpine
COPY ./public /usr/share/nginx/html
- Ajouter des vérifications d’échec courantes
- Supprimez un fichier de
publicet observez l’échec deCOPY; corrigez en ajustant le contexte et.dockerignore. - Introduisez des CRLF dans un script shell ; corrigez avec des LF et
chmod +x. - Forcez un décalage de plateforme ; exécutez avec
--platformpour vérifier le comportement. - Montez en bind un répertoire de données ; testez les permissions via UID correspondants et
:Zavec SELinux.
- Instrumenter un diagnostic rapide (Makefile optionnel)
run:
docker compose up --build
shell:
docker run --rm -it --entrypoint sh myapp:dev
clean:
docker system prune -f
- Documenter les correctifs exacts
- Tenez un court troubleshooting.md avec le texte d’erreur, la cause et la commande utilisée pour corriger.
- Étendre progressivement
- Ajoutez un second service (ex. API) et un réseau défini par l’utilisateur.
- Ajoutez des pulls depuis un registre privé pour valider l’authentification et la gestion des tags.
Conclusion
La plupart des problèmes Docker se répètent d’un projet à l’autre : erreurs de chemin et de contexte, décalages de plateformes, particularités DNS/proxy et permissions sur les montages. Avec un workflow simple, les pratiques modernes BuildKit/Buildx et les correctifs ci‑dessus, vous pouvez diagnostiquer et résoudre rapidement et en sécurité. Démarrez avec le pilote local, capturez ce qui fonctionne et appliquez les mêmes schémas à Docker Compose, Kubernetes et vos pipelines CI.