Débogage des conteneurs Docker : utiliser exec pour entrer dans un conteneur

L’API de l’environnement de test renvoie soudainement un 502. docker ps affiche le conteneur « Up 2 hours » — tout semble normal. Les logs ne montrent qu’un froid « Connection refused ».
C’est frustrant : le conteneur tourne, mais vous ne savez pas ce qui se passe à l’intérieur. La configuration est-elle correcte ? Les processus sont-ils démarrés ? Les ports sont-ils en écoute ? Il faut souvent « entrer » dans le conteneur pour le vérifier, comme ouvrir une boîte noire.
Au début avec Docker, je ne savais pas non plus comment « entrer » dans un conteneur. On lit docker exec, docker attach, ou « redémarrez le conteneur ». Après quelques erreurs, on comprend qu’il existe une bonne façon de déboguer.
Cet article explique comment utiliser docker exec pour diagnostiquer un conteneur : différence avec attach, outils manquants dans l’image, et astuces pratiques. Une fois maîtrisé, vous n’aurez plus besoin du seul « redémarrer et espérer ».
Bases de docker exec — entrer correctement dans un conteneur
La méthode la plus simple
Pour un conteneur en cours d’exécution :
docker exec -it my-nginx bash
Trois éléments clés :
-it:-igarde l’entrée standard ouverte,-talloue un terminal — vous « dialoguez » avec le conteneurmy-nginx: nom du conteneur, ou son ID (docker exec -it abc123def456 bash)bash: commande à lancer dans le conteneur
Le prompt ressemble à root@abc123def456:/# : vous êtes dans le conteneur et pouvez exécuter des commandes Linux habituelles.
Si bash n’existe pas
Erreur fréquente :
$ docker exec -it my-alpine bash
OCI runtime exec failed: exec failed: container_linux.go:380:
starting container process caused: exec: "bash": executable file not found
Souvent Alpine n’inclut que sh, pas bash. Essayez :
docker exec -it my-alpine sh
En pratique : bash d’abord, sinon sh — cela couvre la plupart des cas.
Utiliser l’ID du conteneur
# Voir l'ID
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED
abc123def456 nginx "/docker-entrypoint.…" 2 hours ago
# Préfixe de 3–4 caractères suffit
$ docker exec -it abc1 bash
Docker fait correspondre le préfixe tant qu’il est unique — pratique avec beaucoup de conteneurs.
Quitter le conteneur correctement
exit ou Ctrl+D :
root@abc123def456:/# exit
exit
$
Avec exec, le conteneur ne s’arrête pas à la sortie. Point important pour la suite.
exec vs attach — ne plus les confondre
Différence fondamentale
Beaucoup de tutoriels citent exec et attach sans clarifier. J’ai déjà arrêté un conteneur en production en utilisant attach par erreur.
En bref :
- docker exec : lance un nouveau processus dans le conteneur (nouvelle fenêtre)
- docker attach : se connecte au processus principal (PID 1), comme un partage d’écran
Exemple : docker attach my-nginx, puis Ctrl+C ou exit — le processus principal (Nginx) reçoit le signal de fin et le conteneur s’arrête.
Avec docker exec -it my-nginx bash, bash est indépendant ; quitter bash n’affecte pas Nginx.
Quand utiliser quoi ?
Dans 99 % des cas, utilisez exec.
attach sert surtout quand vous devez interagir directement avec le processus principal :
- programme interactif (REPL Python, etc.)
- voir la sortie du processus principal en direct
- plusieurs terminaux « synchronisés » sur le même tty
Pour consulter des fichiers, modifier une config ou lancer des commandes, exec est plus sûr.
Tableau comparatif
| Caractéristique | docker exec | docker attach |
|---|---|---|
| Nouveau processus | ✓ Oui | ✗ Non |
| Conteneur arrêté à exit | ✗ Non | ✓ Oui (risqué) |
| Commande arbitraire | ✓ Oui | ✗ Non |
| Terminaux indépendants | ✓ Oui | ✗ Non (tty partagé) |
| Recommandation débogage | ⭐⭐⭐⭐⭐ | ⭐ |
attach vise surtout la sortie du conteneur, pas le débogage quotidien.
Outils manquants dans le conteneur
Pourquoi si peu de commandes ?
Dans le conteneur, vim ou curl peuvent manquer — frustrant au début.
C’est la philosophie des images Docker : le minimum indispensable. Ubuntu complet : centaines de Mo ; Alpine : ~5 Mo, en retirant vim, curl, ping, etc.
Installation temporaire
Selon la distribution :
Debian/Ubuntu (apt/apt-get) :
apt-get update
apt-get install -y vim curl wget net-tools
apt-get install -y iputils-ping dnsutils
CentOS/Red Hat (yum) :
yum install -y vim curl wget
Alpine (apk) :
apk update
apk add vim curl bash
Identifier la distribution
cat /etc/os-release
which apt-get # Debian/Ubuntu
which yum # CentOS/Red Hat
which apk # Alpine
Souvent on tente apt-get update et on change si erreur.
Est-ce acceptable ?
Dev : installation libre ; au redémarrage le conteneur repart à zéro.
Production : uniquement en urgence pour le diagnostic ; ensuite intégrer les outils au Dockerfile.
Raisons : sécurité des paquets temporaires, reproductibilité (perdus au redémarrage).
Solution durable : Dockerfile
FROM nginx:latest
RUN apt-get update && apt-get install -y \
vim \
curl \
wget \
net-tools \
iputils-ping \
&& rm -rf /var/lib/apt/lists/*
# autres configs...
rm -rf /var/lib/apt/lists/* réduit la taille de l’image.
Astuce sans vim
cat ou less suffisent souvent :
cat /etc/nginx/nginx.conf
less /etc/nginx/nginx.conf # q pour quitter
head -n 20 /etc/nginx/nginx.conf
Modification d’urgence avec sed :
sed -i 's/listen 80/listen 8080/g' /etc/nginx/nginx.conf
Entrer avec un utilisateur spécifique
Pourquoi préciser l’utilisateur ?
root@abc123:/app# cat /var/log/app.log
cat: /var/log/app.log: Permission denied
Le conteneur peut tourner en non-root (bonne pratique en production) ; exec hérite souvent de cet utilisateur.
Entrer en root
docker exec -it --user root my-app bash
# ou
docker exec -it -u root my-app bash
UID ou nom d’utilisateur
docker exec -it --user 1000 my-app bash
docker exec -it --user appuser my-app bash
docker exec -it --user 1000:1000 my-app bash
Utile pour reproduire les problèmes de permissions :
docker exec -it --user appuser my-app bash
appuser@abc123:/app$ touch /data/test.txt
touch: cannot touch '/data/test.txt': Permission denied
Quand root est nécessaire
- Config système sous
/etc/ - Installation de paquets (apt, yum)
- Logs système sous
/var/log/ chmod,chown- Outils réseau comme
tcpdump,netstat(souvent root)
Évitez root si possible, surtout en production.
Rappel sécurité
Test : usage libre, redémarrage = reset.
Production :
- consultation → OK
- modification temporaire → à documenter
- compilation ou install dans le conteneur en cours → à éviter ; passer par le Dockerfile
Le conteneur est une infrastructure immuable : les changements runtime disparaissent au redémarrage. Le root du conteneur peut partager UID 0 avec l’hôte selon la config — d’où l’intérêt du non-root.
Astuces et scénarios courants
Une seule commande (sans shell interactif)
Sans -it :
docker exec my-nginx ls -la /etc/nginx/
docker exec my-nginx cat /etc/nginx/nginx.conf
docker exec my-nginx ps aux
docker exec my-nginx netstat -tlnp
docker exec my-nginx curl -I localhost:80
Idéal pour scripts et checks rapides :
if docker exec my-app curl -f http://localhost:8080/health; then
echo "App is healthy"
else
echo "App is down!"
fi
Flux de débogage standard
1. État du conteneur
docker ps -a
2. Logs
docker logs my-app --tail 100
docker logs my-app -f
3. Processus
docker exec my-app ps aux
4. Ports
docker exec my-app netstat -tlnp
docker exec my-app ss -tlnp
5. Disponibilité du service
docker exec my-app curl localhost:8080
docker exec my-app telnet localhost 8080
6. Configuration
docker exec my-app cat /etc/nginx/nginx.conf
docker exec my-app cat /app/config.yaml
7. Espace disque
docker exec my-app df -h
Combinaisons utiles
docker exec my-app env | grep DATABASE
docker exec my-app find /app -name "*.log"
docker exec my-app ls -la /app/
docker stats my-app
Plusieurs conteneurs
for container in $(docker ps -q); do
echo "Container: $container"
docker exec $container free -h
echo "---"
done
Réseau
docker exec containerA ping containerB
docker exec my-app ping -c 3 google.com
docker exec my-app nslookup google.com
docker inspect my-app | grep IPAddress
docker exec my-app ip addr show
Conteneur qui redémarre en boucle
Méthode 1 — commande de démarrage remplacée
docker run -it --name debug-app my-app-image sh
Méthode 2 — conteneur arrêté
docker start my-app
docker logs my-app
docker exec -it my-app bash
Ces habitudes viennent du terrain ; une fois les commandes acquises, le diagnostic va plus vite.
Conclusion
L’essentiel du débogage Docker :
docker exec -it nom-conteneur bash (ou sh) est la voie la plus sûre — la sortie n’arrête pas le conteneur.
Ne confondez pas exec et attach — attach peut arrêter le conteneur à la sortie.
Outils manquants : installation temporaire (apt/yum/apk), solution durable dans le Dockerfile.
Root : --user root si besoin, avec parcimonie en production.
Ordre : logs → processus → config → réseau.
Checklist rapide :
- Conteneur en cours ? (
docker ps) - Erreurs dans les logs ? (
docker logs) - Processus actifs ? (
docker exec ps aux) - Ports en écoute ? (
docker exec netstat -tlnp) - Config correcte ? (
docker exec cat config) - Espace disque ? (
docker exec df -h) - Réseau OK ? (
docker exec curl/ping)
Flux complet de débogage des conteneurs Docker
Étapes complètes pour diagnostiquer un conteneur avec exec : commandes, installation d'outils, gestion des permissions et méthode systématique
⏱️ Estimated time: 30 min
- 1
Step 1: Entrer dans le conteneur : comprendre exec et attach
Différence essentielle : exec crée un nouveau processus dans le conteneur (recommandé, n'impacte pas le processus principal), attach se connecte au stdin/stdout du processus principal (déconseillé — quitter arrête le conteneur).
Commandes de base :
• docker exec -it nom-conteneur /bin/bash (entrer dans bash)
• docker exec -it nom-conteneur sh (entrer dans sh, courant sur Alpine)
• docker exec nom-conteneur commande (exécuter une commande sans session interactive)
Paramètres :
• -i : garder STDIN ouvert (mode interactif)
• -t : allouer un pseudo-terminal (sortie formatée)
• -it combinés : usage optimal
Cas d'usage : exec pour déboguer, installer des outils, modifier la config ; attach surtout pour voir la sortie des logs en temps réel. - 2
Step 2: Résoudre l'absence d'outils et les problèmes de permissions
Installation d'outils :
• Debian/Ubuntu : apt-get update && apt-get install -y nom-outil
• Alpine : apk add --no-cache nom-outil
• CentOS/RHEL : yum install -y nom-outil
Système de fichiers en lecture seule : remonter en écriture d'abord :
docker exec -u root nom-conteneur sh -c 'mount -o remount,rw /'
Permissions utilisateur :
• -u root pour les droits root : docker exec -u root nom-conteneur
• --user uid:gid pour un utilisateur spécifique
• Vérifier l'utilisateur courant : whoami
• Voir les permissions : ls -la
• Modifier : chmod 755 fichier, chown user:group fichier
Attention : root en production avec parcimonie ; documenter les changements et les reporter dans le Dockerfile — les modifications sont perdues au redémarrage du conteneur. - 3
Step 3: Flux de débogage systématique
Checklist (dans l'ordre) :
1) Logs : docker logs nom-conteneur, ou /var/log dans le conteneur
2) Processus : ps aux | grep nom-processus
3) Ports : netstat -tuln | grep port, ou ss -tuln
4) Config : cat /chemin/vers/config
5) Disque : df -h
6) Réseau : curl http://localhost:port, ping hostname
Flux : logs pour l'erreur → processus pour confirmer le service → config pour exclure une mauvaise config → réseau pour la connectivité.
Cet ordre résout plus de 90 % des problèmes de conteneurs.
FAQ
Pourquoi privilégier exec plutôt qu'attach pour entrer dans un conteneur ?
• exec : crée un nouveau processus, n'affecte pas le processus principal, le conteneur continue à l'arrêt de la session
• attach : se connecte au stdin/stdout du processus principal, quitter peut arrêter le conteneur
exec convient donc au débogage ; attach sert surtout à suivre la sortie des logs en temps réel.
Que faire si le conteneur n'a ni bash ni sh ?
• Autre shell : docker exec -it nom-conteneur /bin/ash (courant sur Alpine)
• Commande directe : docker exec nom-conteneur commande (sans shell interactif)
• Shells disponibles : docker exec nom-conteneur ls /bin/
• busybox : docker exec -it nom-conteneur busybox sh sur certaines images minimales
Pour un débogage interactif régulier, préinstaller bash ou sh dans le Dockerfile.
Comment installer des outils dans un conteneur à système de fichiers en lecture seule ?
1. docker exec -u root nom-conteneur sh -c 'mount -o remount,rw /'
2. Puis installer normalement :
docker exec -u root nom-conteneur apt-get update
docker exec -u root nom-conteneur apt-get install -y nom-outil
Les changements sont perdus au redémarrage — ajoutez les outils au Dockerfile ou utilisez un build multi-étapes.
Le conteneur n'accède pas au réseau externe : que faire ?
1. Mode réseau : docker inspect nom-conteneur | grep NetworkMode
2. DNS : docker exec nom-conteneur nslookup google.com
3. Connectivité : docker exec nom-conteneur ping -c 3 8.8.8.8
4. Pare-feu : docker exec nom-conteneur iptables -L
5. Réseau personnalisé : docker network inspect nom-reseau
Causes fréquentes : DNS mal configuré, règles pare-feu, mode réseau incorrect.
Comment quitter une session exec sans arrêter le conteneur ?
• exit ou Ctrl+D : sortie normale, le conteneur continue
• Ctrl+P puis Ctrl+Q : détachement, le conteneur continue
• Fermer le terminal : avec -it, le conteneur reste actif
Évitez Ctrl+C après docker attach — cela peut arrêter le processus principal. Avec exec, la sortie n'affecte pas le processus principal.
7 min de lecture · Publié le: 18 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
Gestion des logs Docker en pratique : de la configuration des drivers à la collecte centralisée
Analyse approfondie des drivers de logs Docker, de la rotation et des solutions de collecte centralisée, avec bonnes pratiques et pièges à éviter en production
Partie 35 sur 38
Suivant
Le conteneur Docker quitte dès le démarrage ? Guide complet de dépannage (codes 137/1)
Votre conteneur Docker passe immédiatement en Exited au démarrage ? Ce guide propose une méthode systématique : sens des codes de sortie 137/1, dépannage en quatre étapes et solutions pour les cinq échecs les plus fréquents.
Partie 37 sur 38



Commentaires
Connectez-vous avec GitHub pour laisser un commentaire