Dépannage Docker Compose : 5 erreurs courantes et solutions rapides

Vendredi, 15 h 30. Il reste deux heures avant la deadline de commit.
Dans le terminal, une ligne rouge : Error starting userland proxy: Bind for 0.0.0.0:8080 failed: port is already allocated. Hier tout marchait, aujourd’hui plus rien.
Ctrl+C, on relance. Même erreur. Google « docker compose port already allocated », cinq ou six fils Stack Overflow, chaque solution testée : redémarrer Docker, supprimer les conteneurs, changer le port… le message ne bouge pas.
Les erreurs Docker Compose font souvent des dizaines de lignes ; la phrase utile est à la ligne 23, alors que vous paniquez dès la ligne 1. Cet article résume deux ans de galères — 5 catégories d’erreurs Docker Compose les plus fréquentes, chacune en « symptômes → cause → solutions ». Vous verrez que 90 % des erreurs se règlent en 5 minutes — à condition de savoir par où commencer.
Bases du diagnostic — 3 outils essentiels
Avant de traiter une erreur précise, voici les trois commandes que j’utilise des dizaines de fois par jour pour Docker Compose.
Outil 1 : docker-compose ps — état rapide
Cette commande indique quels conteneurs tournent et lesquels sont tombés.
docker-compose ps
Regardez la colonne State :
Up— tout va bienExit— échec au démarrage ou crashRestarting— redémarrages en boucle, souvent un problème de commande de démarrage
Quand un service est en Exit 1, je sais qu’il faut ouvrir les logs.
Outil 2 : docker-compose logs — pistes dans les journaux
C’est le cœur du diagnostic.
# Tous les services
docker-compose logs
# Un seul service (nginx)
docker-compose logs nginx
# Suivi en temps réel (comme tail -f)
docker-compose logs -f
# 100 dernières lignes
docker-compose logs --tail 100 nginx
Les logs Docker peuvent être verbeux, mais dans 90 % des cas l’erreur réelle est dans les dernières lignes. Remontez et cherchez ERROR, failed, cannot.
Outil 3 : docker inspect — analyse approfondie (si besoin)
Quand les deux premiers outils ne suffisent pas.
# Configuration complète du conteneur
docker inspect nom_conteneur
# État uniquement
docker inspect --format='{{.State.Status}}' nom_conteneur
# Adresse IP
docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nom_conteneur
Flux générique (à retenir)
Ne paniquez pas, suivez cet ordre :
docker-compose ps— quel service est en pannedocker-compose logs [service]— message d’erreur précisdocker inspect— analyse fine (souvent inutile)
Les outils sont prêts. Passons aux 5 erreurs les plus fréquentes.
Conflit de ports — « port is already allocated »
Je vois cette erreur constamment :
Error starting userland proxy: Bind for 0.0.0.0:8080 failed: port is already allocated
Ou :
ERROR: for nginx Cannot start service nginx: driver failed programming external connectivity on endpoint xxx: Bind for 0.0.0.0:80 failed: port is already allocated
Pourquoi ?
En général, trois cas :
- Après
docker-compose up, vous avez fait Ctrl+C sansdocker-compose down— les conteneurs tournent encore en arrière-plan - Vous avez changé les ports dans docker-compose.yml, mais les anciens conteneurs n’ont pas été supprimés
- Un autre programme sur la machine occupe le port (Nginx local, MySQL, etc.)
Solutions (du plus simple au plus complexe)
Solution 1 : tout nettoyer et relancer (efficace dans 90 % des cas)
docker-compose down
docker-compose up -d
Pour moi, c’est presque infaillable. down arrête et supprime les conteneurs, mais garde les volumes.
Solution 2 : trouver le conteneur qui occupe le port
Si la solution 1 échoue, il peut y avoir un « conteneur fantôme » hors projet :
# Tous les conteneurs (y compris arrêtés)
docker ps -a | grep 8080
# Puis arrêter et supprimer
docker stop <container_id>
docker rm <container_id>
Solution 3 : vérifier les processus docker-proxy
Parfois le conteneur est parti, mais docker-proxy reste.
# Processus docker-proxy
ps aux | grep docker-proxy | grep 8080
# S'il reste des résidus, redémarrer Docker
sudo systemctl restart docker # Linux
# Sur Mac : menu Docker Desktop → Restart
Solution 4 : occupation du port sur l’hôte
Un programme local peut bloquer le port.
# Linux/Mac
lsof -i :8080
netstat -tlnp | grep 8080
# Windows
netstat -ano | findstr 8080
Arrêtez ce programme ou changez le port dans docker-compose.yml.
Solution 5 : modifier le mapping de ports (dernier recours)
Éditez docker-compose.yml :
services:
web:
ports:
- "8081:80" # 8080 → 8081
Mes conseils
Habitude : arrêter avec docker-compose down, pas seulement Ctrl+C. J’avais pris l’habitude du Ctrl+C rapide et je me battais avec les conflits de ports toutes les deux semaines ; depuis le changement, l’erreur a presque disparu.
En dev, préférez des ports non standards : 8080, 3307 plutôt que 80 ou 3306, pour éviter les conflits avec les services système.
Problèmes réseau — « network declared as external but could not be found »
Message typique :
ERROR: Network my_network declared as external, but could not be found. Please create the network manually using `docker network create my_network` and try again.
Pourquoi cette erreur ?
Piège fréquent : si un réseau est marqué external: true dans docker-compose.yml, Docker suppose qu’il existe déjà et ne le crée pas. S’il ne le trouve pas, erreur.
Scénarios courants :
- Config copiée d’ailleurs avec un réseau external que vous n’avez pas créé
- Redémarrage de Docker et perte de certaines configs réseau
- Faute de casse dans le nom (les noms de réseau Docker sont sensibles à la casse)
Solutions
Solution 1 : lister les réseaux et vérifier le nom
docker network ls
Le réseau réel peut s’appeler myproject_app_network au lieu de app_network — Docker Compose ajoute souvent un préfixe projet.
Solution 2 : créer le réseau manquant
docker network create my_network
Solution 3 : corriger le fichier
Trois approches :
# A : retirer external, laisser Compose créer le réseau
networks:
app_network:
driver: bridge
# B : name pour fixer le nom exact
networks:
app_network:
external: true
name: my_actual_network_name
# C : créer le réseau à la main puis external
Je préfère l’option A. Sauf besoin de partager un réseau entre plusieurs projets Compose, laisser Compose gérer le réseau est plus simple.
Solution 4 : nettoyer et reconstruire (après perte de réseau)
docker-compose down
docker network prune # réseaux inutilisés
docker-compose up -d
Éviter les pièges
- Distinguer réseaux external (partagés entre projets) et réseaux gérés par Compose (un seul projet)
- Utiliser
namepour éviter la confusion avec les préfixes automatiques - Documenter dans le README les réseaux external à créer avant le premier
up
Échec de build — « service failed to build »
Ne paniquez pas devant :
ERROR: Service 'app' failed to build: Build failed
Astuce clé : remonter dans les logs
« service failed to build » est un résumé ; le vrai problème est plus haut. Remontez 50 à 100 lignes et cherchez ERROR, failed, cannot, not found, permission denied.
La première fois, j’ai fixé la dernière ligne pendant longtemps. L’erreur réelle était souvent « npm install failed » ou « fichier introuvable », noyée dans la sortie.
Sous-types fréquents
Type 1 : fichier introuvable
COPY failed: stat /var/lib/docker/tmp/.../package.json: no such file or directory
Causes :
- Mauvais chemin de
build context - Fichiers nécessaires exclus par
.dockerignore
Correction :
# Vérifier context dans docker-compose.yml
services:
app:
build:
context: ./my-app # chemin correct ?
dockerfile: Dockerfile
# Tester sans .dockerignore
mv .dockerignore .dockerignore.bak
docker-compose build app
Type 2 : échec d’installation de dépendances
npm ERR! 404 Not Found - GET https://registry.npmjs.org/xxx
Ou :
E: Unable to locate package xxx
Causes : nom de paquet, version inexistante, réseau
Correction :
# Miroir npm dans le Dockerfile
RUN npm config set registry https://registry.npmmirror.com
RUN npm install
# Ou miroir apt
RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list
RUN apt-get update && apt-get install -y xxx
Type 3 : mémoire insuffisante
The command '/bin/sh -c npm install' returned a non-zero code: 137
signal: killed
Le code 137 indique souvent un manque de mémoire.
Correction :
- Docker Desktop → Settings → Resources → Memory, au moins 4 Go
- Ou dans le Dockerfile :
RUN npm install --max_old_space_size=4096
Type 4 : erreur de syntaxe Dockerfile
Instruction incorrecte, mauvais chemin COPY, etc.
Test isolé :
cd répertoire_build
docker build -t test-build .
Message d’erreur plus lisible.
Méthodes de debug
Rebuild sans cache :
docker-compose build --no-cache service_name
Parfois une couche en cache est corrompue.
Voir la config résolue :
docker-compose config
Affiche la config complète après résolution — utile pour les chemins.
Mon expérience
- Garder une version qui build comme référence
- Modifier le Dockerfile par petits pas
- Build lent : multi-stage ou ordre des instructions (couches stables en premier)
Conteneur qui sort juste après le démarrage — « exited with code X »
Plus discret : l’image build, le conteneur démarre, puis s’arrête tout de suite.
docker-compose ps peut afficher :
Name State
app_web_1 Exit 1
app_db_1 Up
Codes de sortie (à retenir)
- Exit 0 : sortie « normale » — parfois problématique pour un service (commande finie)
- Exit 1 : erreur applicative (le plus courant)
- Exit 137 : manque de mémoire (OOM) ou kill
- Exit 139 : segmentation fault
- Exit 143 : signal SIGTERM (arrêt manuel en général)
Étapes de diagnostic
Étape 1 : logs
docker-compose logs service_name
Dans 90 % des cas, la raison y est.
Étape 2 : entrer dans le conteneur pour déboguer
Si les logs ne suffisent pas, gardez le conteneur vivant :
services:
app:
command: sleep infinity # empêcher la sortie immédiate
Puis :
docker-compose up -d
docker-compose exec app sh # entrer
# exécuter à la main la commande de démarrage d'origine
Solutions ciblées
Exit 0 — la commande se termine
Exemple : command: echo "Hello" — une fois fini, le conteneur s’arrête.
Correction : processus long ou bloquant :
# Mauvais
command: echo "Started"
# Bon
command: npm start # processus continu
Exit 1 — erreur applicative
Logs pour la cause : mauvais chemin de config, variable manquante, base pas prête, permissions.
Exit 137 — mémoire
services:
app:
mem_limit: 2g
memswap_limit: 2g
Ou augmenter la RAM allouée à Docker Desktop.
Service dépendant pas prêt
L’app démarre pendant que la base s’initialise encore → crash.
Correction : depends_on + healthcheck :
services:
app:
depends_on:
db:
condition: service_healthy
db:
image: postgres
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
L’app attend que db soit vraiment prêt.
Pièges personnels
Un conteneur en Exit 1 en boucle : log « Config file not found ». Cause : chemin relatif au fichier de config — le répertoire de travail dans le conteneur n’était pas celui prévu. Passage en chemin absolu : réglé.
Une fois, mauvais mot de passe base — l’app crashait au démarrage, le log était clair, mais j’avais mal lu… 20 minutes perdues.
Permissions — « permission denied »
Fréquent avec les volumes montés :
Error: EACCES: permission denied, open '/app/data/config.json'
Ou « Permission denied » dans les logs sans savoir quel fichier.
Pourquoi ?
UID/GID dans le conteneur ≠ propriétaire des fichiers sur l’hôte. Exemple :
- Fichiers hôte : votre utilisateur (UID 1000)
- App dans le conteneur : www-data (UID 33)
- www-data ne peut pas lire/écrire → erreur
Solutions
Solution 1 : user avec UID/GID (recommandé en dev)
services:
app:
user: "${UID}:${GID}"
volumes:
- ./data:/app/data
Lancement :
UID=$(id -u) GID=$(id -g) docker-compose up
Ou dans .env :
# .env
UID=1000
GID=1000
Solution 2 : droits sur l’hôte
chmod -R 777 ./data # prudent : risque sécurité
# ou
chmod -R 755 ./data
chown -R $(id -u):$(id -g) ./data
Solution 3 : SELinux (CentOS/RHEL)
volumes:
- ./data:/app/data:z # partage entre conteneurs
# ou
- ./config:/app/config:Z # privé à ce conteneur
z = partagé, Z = privé au conteneur.
Solution 4 : named volume au lieu de bind mount
services:
app:
volumes:
- app_data:/app/data
volumes:
app_data: # Docker gère les permissions
Inconvénient : édition directe sur l’hôte plus difficile.
Solution 5 : entrypoint qui ajuste les droits
# entrypoint.sh
#!/bin/sh
chown -R appuser:appuser /app/data
exec "$@"
COPY entrypoint.sh /
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["node", "app.js"]
Mes conseils
- Production : named volumes, moins de soucis de permissions
- Dev :
useravec UID/GID pour éditer sur l’hôte - Éviter 777 sauf si vous faites totalement confiance au code dans le conteneur
Une fois la logique UID/GID comprise, ce type d’erreur devient rare.
Synthèse des astuces de debug
Flux standard (fiable)
1. docker-compose ps → état, service en cause
2. docker-compose logs <svc> → message d'erreur
3. docker-compose config → syntaxe et config
4. docker inspect <conteneur> → si besoin
5. Test isolé → démarrer seul le service problématique
Commandes de nettoyage (entretien régulier)
# Arrêter et supprimer les conteneurs (garder les volumes)
docker-compose down
# Supprimer aussi les volumes (attention)
docker-compose down -v
# Ressources inutilisées (réseaux, images…)
docker system prune
# Tout nettoyer (y compris images)
docker system prune -a
# Rebuild sans cache
docker-compose build --no-cache
# Espace disque Docker
docker system df
Chaque vendredi avant de partir, je lance docker system prune. Une fois Docker occupait 50 Go ; après nettoyage, 10 Go.
Mesures préventives
Validation de config :
docker-compose config
Vérifie le YAML avant up.
Healthcheck :
services:
web:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80/health"]
interval: 30s
timeout: 10s
retries: 3
Détecte un service « Up » mais réellement unhealthy.
Politique de redémarrage :
services:
app:
restart: unless-stopped # recommandé
# restart: always
# restart: on-failure
Variables d’environnement centralisées :
# .env
DB_PASSWORD=your_password
API_KEY=your_key
# docker-compose.yml
services:
app:
environment:
- DB_PASSWORD=${DB_PASSWORD}
- API_KEY=${API_KEY}
Modifier la config sans toucher au YAML ; pratique en équipe.
Conclusion
Retour au vendredi 15 h 30 : deadline proche, conteneurs qui refusent de démarrer. Vous savez maintenant :
- Respirer
- Identifier la catégorie (port, réseau, build, sortie, permissions)
- Appliquer les solutions de la section, du plus simple au plus complexe
- Si blocage : les logs ont presque toujours la réponse
Docker Compose n’est pas effrayant ; ce qui manque souvent, c’est une méthode. Retenez ces 5 familles d’erreurs et leurs correctifs — la prochaine fois, 5 minutes suffiront souvent.
Dernière idée : base de connaissances d’équipe avec pièges et solutions. Notre wiki « Problèmes Docker courants » fait gagner énormément de temps aux nouveaux.
Quelle erreur Docker Compose bizarre avez-vous rencontrée ? Partagez en commentaire — ça peut aider d’autres lecteurs.
Flux complet de dépannage des erreurs Docker Compose
5 erreurs courantes et solutions rapides, flux systématique pour localiser le problème en 5 minutes
⏱️ Estimated time: 5 min
- 1
Step 1: Maîtriser 3 outils de diagnostic essentiels
Outil 1 : docker-compose ps — état rapide
• Indique quels conteneurs tournent et lesquels sont tombés
• Colonne State :
- Up : fonctionnement normal
- Exit : échec au démarrage ou crash en cours d'exécution
- Restarting : redémarrages en boucle, souvent un problème de commande de démarrage
Outil 2 : docker-compose logs — pistes dans les journaux
• Logs d'un service : docker-compose logs web
• 50 dernières lignes : docker-compose logs --tail=50 web
• Suivi en temps réel : docker-compose logs -f web
Outil 3 : docker-compose config — valider la configuration
• Vérifier la syntaxe de docker-compose.yml : docker-compose config
• Vérifier les variables d'environnement : docker-compose config --resolve-env-vars - 2
Step 2: Erreur 1 : conflit de ports — diagnostic et correction
Symptômes :
• Error starting userland proxy: Bind for 0.0.0.0:8080 failed: port is already allocated
Cause :
• Port déjà utilisé par un autre processus
• Ancien conteneur non arrêté ou autre service système sur le même port
Solutions :
1. Vérifier l'occupation du port
• lsof -i :8080
• netstat -tuln | grep 8080
2. Arrêter le processus occupant
• kill -9 PID
• docker-compose down
3. Modifier le port
• Changer ports dans docker-compose.yml
• Exemple : "8081:8080"
4. Port dynamique
• Ne pas fixer le port hôte, laisser Docker attribuer - 3
Step 3: Erreurs 2 à 5 : réseau, build, sortie de conteneur, permissions
Erreur 2 : réseau
• Symptômes : network not found, container name resolution failed
• Solutions :
- Vérifier : docker network ls
- Créer un réseau : docker network create my-network
- Spécifier dans docker-compose.yml : networks: my-network
Erreur 3 : échec de build
• Symptômes : build failed, Dockerfile not found
• Solutions :
- Vérifier la syntaxe du Dockerfile
- Vérifier le contexte de build
- Vérifier les fichiers de dépendances
- Logs détaillés : docker-compose build --no-cache
Erreur 4 : sortie de conteneur
• Symptômes : Exited with code 1, Restarting
• Solutions :
- docker-compose logs
- Vérifier la commande de démarrage
- Vérifier les variables d'environnement
- Vérifier les services dépendants
Erreur 5 : permissions
• Symptômes : Permission denied, Cannot connect to Docker daemon
• Solutions :
- chmod pour corriger les droits
- État du daemon : sudo systemctl status docker
- Droits utilisateur : sudo usermod -aG docker $USER
FAQ
Quels sont les outils clés pour dépanner Docker Compose ?
1) docker-compose ps — état rapide :
• Indique quels conteneurs tournent et lesquels sont tombés
• Colonne State (Up = normal, Exit = échec ou crash, Restarting = boucle de redémarrage)
2) docker-compose logs — pistes dans les journaux :
• Logs d'un service : docker-compose logs web
• 50 dernières lignes : docker-compose logs --tail=50 web
• Suivi en temps réel : docker-compose logs -f web
3) docker-compose config — valider la configuration :
• Syntaxe docker-compose.yml : docker-compose config
• Variables d'environnement : docker-compose config --resolve-env-vars
Comment résoudre un conflit de ports ?
Cause : port occupé par un autre processus, ancien conteneur non arrêté ou autre service système.
Solutions :
1) Vérifier l'occupation (lsof -i :8080 ou netstat -tuln | grep 8080)
2) Arrêter le processus (kill -9 PID ou docker-compose down)
3) Modifier le port dans docker-compose.yml (ex. "8081:8080")
4) Port dynamique (ne pas fixer le port hôte, laisser Docker attribuer)
Comment dépanner les problèmes réseau Docker Compose ?
Cause : configuration réseau incorrecte, résolution de noms entre conteneurs impossible.
Solutions :
1) Vérifier les réseaux (docker network ls)
2) Créer un réseau personnalisé (docker network create my-network)
3) Spécifier le réseau dans docker-compose.yml (networks: my-network)
4) S'assurer que les services partagent le même nom de réseau
Comment dépanner une sortie de conteneur ?
Causes possibles :
• Commande de démarrage incorrecte
• Variables d'environnement manquantes
• Service dépendant pas prêt
Solutions :
1) Consulter les logs (docker-compose logs)
2) Vérifier CMD ou ENTRYPOINT
3) Vérifier .env et les variables d'environnement
4) Vérifier que les services dépendants sont démarrés et prêts
5) Vérifier healthcheck si configuré
Comment dépanner Docker Compose de façon systématique ?
1) docker-compose ps pour l'état des conteneurs
2) docker-compose logs pour les erreurs
3) docker-compose config pour valider le fichier
4) Traiter par type :
• Conflit de ports → occupation → modifier le port ou arrêter le processus
• Réseau → configuration → réseau personnalisé
• Build → Dockerfile → corriger l'erreur de build
• Sortie → logs → corriger la commande de démarrage
• Permissions → droits fichiers → corriger
90 % des erreurs se règlent en 5 minutes si vous savez par où commencer.
Bonne pratique : tenir une base de connaissances d'équipe avec les pièges rencontrés. Notre wiki a une page « Problèmes Docker courants » — les nouveaux y perdent 80 % des erreurs classiques.
11 min de lecture · Publié le: 17 déc. 2025 · Mis à jour le: 27 juil. 2026
Guide pratique Docker
Si vous arrivez depuis la recherche, le plus rapide est de passer à l’article précédent ou suivant de cette série.
Précédent
Dépendances Docker Compose : healthcheck pour l'ordre de démarrage des bases de données
Guide détaillé de depends_on et healthcheck dans Docker Compose, avec exemples pratiques pour résoudre les échecs de démarrage dus à une base non prête — modèles complets PostgreSQL et MySQL.
Partie 9 sur 38
Suivant
Déploiement Docker Compose en production : healthcheck, redémarrage et journaux
Guide pratique Docker Compose en production : configuration du healthcheck, politique de redémarrage et gestion des journaux. De la mort apparente du conteneur à la récupération automatique, sans saturer le disque.
Partie 11 sur 38



Commentaires
Connectez-vous avec GitHub pour laisser un commentaire