Changer le thème

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

Easton editorial illustration: deployment checkpoint lane

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 bien
  • Exit — échec au démarrage ou crash
  • Restarting — 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 :

  1. docker-compose ps — quel service est en panne
  2. docker-compose logs [service] — message d’erreur précis
  3. docker 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 :

  1. Après docker-compose up, vous avez fait Ctrl+C sans docker-compose down — les conteneurs tournent encore en arrière-plan
  2. Vous avez changé les ports dans docker-compose.yml, mais les anciens conteneurs n’ont pas été supprimés
  3. 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 :

  1. Config copiée d’ailleurs avec un réseau external que vous n’avez pas créé
  2. Redémarrage de Docker et perte de certaines configs réseau
  3. 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 name pour é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 : user avec 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 :

  1. Respirer
  2. Identifier la catégorie (port, réseau, build, sortie, permissions)
  3. Appliquer les solutions de la section, du plus simple au plus complexe
  4. 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. 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. 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. 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 ?
3 outils essentiels :

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 ?
Symptômes : Error starting userland proxy: Bind for 0.0.0.0:8080 failed: port is already allocated.

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 ?
Symptômes : network not found, container name resolution failed.

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 ?
Symptômes : Exited with code 1, Restarting.

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 ?
Flux 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

Commentaires

Connectez-vous avec GitHub pour laisser un commentaire

Easton BlogEaston Blog