Chapitre 312 minIntermédiaire
Les commandes Docker essentielles : run, ps, logs, exec
Par Josselyn C., prof de BTS SIO. Mis à jour le .
À la fin de ce chapitre, tu sauras
- lancer un conteneur avec les bonnes options de docker run ;
- suivre un conteneur avec ps, logs, inspect et stats ;
- lire un code de sortie et choisir une politique de redémarrage ;
- faire le ménage sans effacer de données par erreur.
4 exercices corrigés1 schéma
Les commandes Docker de base servent à lancer un conteneur à partir d'une image (docker run), à voir ce qui tourne (docker ps), à lire ses journaux (docker logs), à entrer dedans (docker exec) et à l'arrêter ou le supprimer (docker stop, docker rm). Ce chapitre les pratique sur un serveur web et une base de données de test, explique le cycle de vie d'un conteneur et les politiques de redémarrage, puis montre comment faire le ménage.
Lancer un conteneur avec docker run
docker run télécharge l'image si elle manque, crée un conteneur et le démarre. Lance un serveur web Nginx :
docker run -d --name web -p 8080:80 nginx:1.30-alpine
| Morceau | Sens |
|---|---|
-d (detached) | En arrière-plan : tu récupères ton terminal |
--name web | Un nom choisi ; sinon Docker en invente un (brave_turing) |
-p 8080:80 | Publie le port 80 du conteneur sur le port 8080 de l'hôte : hôte à gauche, conteneur à droite |
nginx:1.30-alpine | L'image et son étiquette : Nginx 1.30 sur Alpine Linux |
Vérifie depuis l'hôte :
curl -I http://localhost:8080
HTTP/1.1 200 OK
Server: nginx/1.30.4
Content-Type: text/html
Les options de docker run que tu utiliseras le plus :
| Option | Rôle | Exemple |
|---|---|---|
-e VAR=valeur | Définit une variable d'environnement | -e TZ=Europe/Paris |
--env-file fichier | Lit les variables dans un fichier | --env-file .env |
-v ou --mount | Monte un volume ou un dossier (chapitre 6) | -v donnees:/var/lib/mysql |
--network | Branche le conteneur sur un réseau (chapitre 7) | --network gestion |
--restart | Politique de redémarrage | --restart unless-stopped |
--rm | Supprime le conteneur dès qu'il s'arrête | Pour une commande ponctuelle |
-it | Mode interactif avec un terminal | docker run --rm -it alpine:3.24 sh |
--memory, --cpus | Limites de ressources (cgroups) | --memory 512m --cpus 1.5 |
--user | Utilisateur du processus | --user 1000:1000 |
Voir les conteneurs : docker ps
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3f2a9c1e7b4d nginx:1.30-alpine "/docker-entrypoint.…" 12 seconds ago Up 11 seconds 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp web
docker ps n'affiche que les conteneurs en cours d'exécution ; docker ps -a montre aussi ceux qui sont arrêtés, avec leur code de sortie (Exited (0) 3 minutes ago). La colonne PORTS indique que le port 8080 est publié sur toutes les adresses IPv4 (0.0.0.0) et IPv6 ([::]) de l'hôte.
Pour un affichage plus lisible, choisis les colonnes :
docker ps -a --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'
Le cycle de vie d'un conteneur
Un conteneur passe par plusieurs états. docker run enchaîne docker create (le conteneur existe, état created) et docker start (état running).
| Commande | Effet |
|---|---|
docker stop web | Envoie le signal d'arrêt de l'image (SIGTERM en général) au processus principal, attend 10 secondes, puis envoie SIGKILL s'il tourne encore |
docker kill web | Envoie SIGKILL tout de suite : arrêt brutal, sans nettoyage |
docker start web | Redémarre un conteneur arrêté, avec sa couche inscriptible intacte |
docker restart web | stop puis start |
docker rm web | Supprime un conteneur arrêté ; -f arrête et supprime d'un coup |
Le code de sortie affiché par docker ps -a aide au diagnostic : 0 pour un arrêt normal, 1 pour une erreur de l'application, 128 + n pour un arrêt par le signal numéro n. 137 (128 + 9) signale donc un SIGKILL : un docker kill, un docker stop qui a dû forcer, ou le noyau qui a tué le processus faute de mémoire. 143 (128 + 15) signale un SIGTERM que l'application n'a pas intercepté.
Les politiques de redémarrage
L'option --restart dit au démon quoi faire quand le conteneur s'arrête :
| Politique | Comportement |
|---|---|
no (par défaut) | Jamais de redémarrage automatique |
on-failure[:n] | Redémarre si le code de sortie n'est pas 0, au plus n fois si on le précise |
always | Redémarre toujours ; un conteneur arrêté à la main repart au prochain démarrage du démon |
unless-stopped | Comme always, sauf si tu l'as arrêté toi-même : il reste alors arrêté, même après un redémarrage du serveur |
Pour un service sur un serveur, unless-stopped est le choix courant : le service survit à un redémarrage de srv-gestion, mais un technicien qui l'arrête pour une maintenance n'a pas la surprise de le voir revenir.
Lire les journaux : docker logs
Un conteneur bien conçu écrit ses journaux sur sa sortie standard et sa sortie d'erreur ; Docker les capture.
docker logs web # tout
docker logs --tail 20 web # les 20 dernières lignes
docker logs -f web # en continu (Ctrl+C pour sortir)
docker logs --since 10m web # les 10 dernières minutes
172.17.0.1 - - [03/Nov/2026:09:31:02 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/8.14.1" "-"
L'adresse 172.17.0.1 est celle de l'hôte sur le réseau par défaut de Docker : la requête de curl est passée par la publication de port. Le chapitre 10 explique comment conserver et centraliser ces journaux.
Entrer dans un conteneur : docker exec
docker exec lance une commande dans un conteneur qui tourne déjà (à ne pas confondre avec docker run, qui en crée un nouveau) :
docker exec web nginx -t # tester la configuration de Nginx
docker exec -it web sh # ouvrir un shell (Ctrl+D pour sortir)
Les images Alpine n'ont que sh ; les images Debian ont bash. Certaines images minimales n'ont aucun shell : c'est volontaire (chapitre 5).
Inspecter et mesurer
| Commande | Ce qu'elle montre |
|---|---|
docker inspect web | Toute la configuration du conteneur, en JSON : image, variables, montages, réseaux, politique de redémarrage |
docker inspect -f '{{.State.Status}} {{.RestartCount}}' web | Un champ précis, avec un modèle Go |
docker stats --no-stream | Processeur, mémoire, réseau et disque de chaque conteneur, à l'instant |
docker top web | Les processus du conteneur, vus depuis l'hôte |
docker port web | Les ports publiés |
docker cp web:/etc/nginx/nginx.conf . | Copie un fichier du conteneur vers l'hôte (ou l'inverse) |
docker events --since 1h | Les événements du démon : créations, démarrages, arrêts, morts |
docker stats --no-stream
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
3f2a9c1e7b4d web 0.00% 9.1MiB / 3.82GiB 0.23% 1.2kB / 1.1kB 0B / 4.1kB 3
La limite affichée, 3,82 Gio, est toute la mémoire de la VM : sans --memory, le conteneur peut tout prendre.
Une base de données de test en une commande
Les variables d'environnement configurent une image au lancement. L'image officielle MySQL lit, entre autres, MYSQL_ROOT_PASSWORD :
docker run -d --name bdd-test \
-e MYSQL_ROOT_PASSWORD='Test-Labo-2026!' \
-p 127.0.0.1:3306:3306 \
mysql:8.4
Le port n'est publié que sur 127.0.0.1 : la base est joignable depuis srv-gestion, pas depuis le réseau. Attends une dizaine de secondes l'initialisation, puis connecte-toi avec le client inclus dans l'image :
docker logs bdd-test 2>&1 | grep 'ready for connections'
docker exec -it bdd-test mysql -uroot -p
Les exercices du cours SQL se font très bien dans un tel conteneur.
Faire le ménage
Les conteneurs arrêtés, les images inutilisées et les volumes orphelins s'accumulent.
| Commande | Ce qu'elle supprime |
|---|---|
docker rm -f web bdd-test | Ces conteneurs, même en marche |
docker container prune | Tous les conteneurs arrêtés |
docker image prune | Les images sans étiquette (dangling) ; -a : toutes les images qu'aucun conteneur n'utilise |
docker volume prune | Les volumes anonymes inutilisés ; -a : aussi les volumes nommés inutilisés |
docker system prune | Conteneurs arrêtés, réseaux inutilisés, images sans étiquette, cache de construction |
docker system df | Rien : affiche la place occupée par chaque catégorie |
Exercices
Exercice 1 sur 4 Écrire la commande Réussi À revoir
Écris la commande qui lance, en arrière-plan, un conteneur nommé wiki à partir de l'image nginx:1.30-alpine, publié sur le port 8090 de l'hôte mais seulement sur l'adresse 192.168.10.179, avec le fuseau horaire Europe/Paris, et qui redémarre après un redémarrage du serveur sauf s'il a été arrêté à la main.
Voir la réponseMasquer la réponse de l'exercice 1
docker run -d --name wiki \
-p 192.168.10.179:8090:80 \
-e TZ=Europe/Paris \
--restart unless-stopped \
nginx:1.30-alpine
Le port de gauche (8090) est celui de l'hôte, précédé de l'adresse d'écoute ; celui de droite (80) est celui où Nginx écoute dans le conteneur. unless-stopped correspond à « sauf s'il a été arrêté à la main ».
Tu avais trouvé ?
Exercice 2 sur 4 Lire les codes de sortie Réussi À revoir
docker ps -a affiche ces trois lignes (colonnes réduites). Pour chacune, dis ce qui s'est probablement passé.
NAMES STATUS
import-csv Exited (0) 2 hours ago
api-frais Exited (137) 5 minutes ago
worker Exited (1) 1 minute ago
Voir la réponseMasquer la réponse de l'exercice 2
import-csv, code 0 : le processus s'est terminé normalement. C'est un conteneur ponctuel qui a fini son travail ; rien d'anormal.api-frais, code 137 = 128 + 9 : le processus a reçuSIGKILL. Soit quelqu'un a lancédocker kill, soit undocker stopa dû forcer après 10 secondes, soit le noyau l'a tué faute de mémoire.docker inspect -f '{{.State.OOMKilled}}' api-fraisaffichetruedans ce dernier cas.worker, code 1 : l'application s'est arrêtée sur une erreur. Lis ses journaux :docker logs --tail 50 worker.
Tu avais trouvé ?
Exercice 3 sur 4 run ou exec ? Réussi À revoir
Un technicien veut vérifier la configuration de Nginx du conteneur web qui tourne. Il tape docker run web nginx -t et obtient Unable to find image 'web:latest' locally. Explique son erreur et donne la bonne commande.
Voir la réponseMasquer la réponse de l'exercice 3
docker run crée un nouveau conteneur à partir d'une image : Docker cherche donc une image appelée web, qui n'existe pas. Pour lancer une commande dans un conteneur qui tourne déjà, il faut docker exec :
docker exec web nginx -t
Tu avais trouvé ?
Exercice 4 sur 4 La politique de redémarrage Réussi À revoir
Le serveur srv-gestion redémarre cette nuit après les mises à jour. Trois conteneurs tournaient hier soir : a lancé avec --restart always, b avec --restart unless-stopped, c sans option. Un quatrième, d, lancé avec --restart unless-stopped, avait été arrêté par docker stop d dans l'après-midi. Lesquels tournent ce matin ?
Voir la réponseMasquer la réponse de l'exercice 4
a(always) : démarré.b(unless-stopped, en marche hier soir) : démarré.c(politiqueno) : arrêté ; personne ne lui a demandé de repartir.d(unless-stopped, arrêté à la main) : arrêté. C'est toute la différence avecalways: avec--restart always,dserait reparti au démarrage du démon.
Tu avais trouvé ?