OS de votre poste :
Parcours Linux · Bash (.sh)
Module 05 · Docker DevOps · TP 01

TP-01 — Exécuter et observer un premier conteneur

Un conteneur peut terminer immédiatement ou continuer à fonctionner en arrière-plan selon le programme lancé. Vous expérimenterez ces comportements, consulterez les journaux et exécuterez des commandes dans un conteneur avant de comparer redémarrage et nouvelle exécution.

Créer un conteneur, observer sa sortie, utiliser --rm, lancer un service en arrière-plan, entrer avec exec et lire les journaux.
Les commandes de l’exercice sont communes aux deux postes.

Objectifs et cours associés

Exécuter un conteneur, suivre ses journaux et utiliser un shell interactif.

Pour réviser les notions utilisées dans ce TP :

Préparation

Prérequis

Configuration pour Linux

Compte student, membre de devops, avec accès sudo ; terminal Linux et systemd.

Guide : Préparer Linux pour les TP

Moteur Docker et Compose disponibles.

Guide : Préparer Docker pour les TP

Dans le terminal Linux, entrer dans student si nécessaire :

Terminal Linux

su - student

Si vous êtes déjà connecté avec student, conserver cette session.

Dépendances

Configuration pour Linux

Utiliser le moteur préparé par le guide commun :

Terminal Linux

docker version
docker compose version

Client et Server doivent être disponibles.
Les services applicatifs seront lancés par les commandes du TP ; ne pas installer les serveurs web ou bases de données sur le poste.

Éléments propres au laboratoire

Les conteneurs créés ici portent les noms asd-tp01-simple, asd-tp01-jetable, asd-tp01-service et asd-tp01-verification, et le label formation.tp=m5-tp01.
Vérifier qu’aucun de ces noms ne correspond à une ressource déjà utilisée :

docker ps -a --filter 'name=asd-tp01-' --format 'table {{.Names}}\t{{.Status}}'
docker image inspect alpine:3.21.3 --format '{{.Id}}'

aucun de ces noms ne doit être occupé au départ.
L’image peut déjà exister ; sinon Docker indique No such image, ce qui est normal avant le premier run.
Noter sa présence pour le nettoyage.
En cas de nom existant, inspecter l’ancien essai et le nettoyer seulement s’il vous appartient.

Créer le dossier du TP puis s’y placer pour préparer les fichiers de travail :

Terminal Linux — Bash

# Créer le dossier indiqué pour les fichiers de travail du TP.
mkdir -p ~/devops-formation/tp-05-01

# Se placer dans ce dossier pour préparer les dépendances.
cd ~/devops-formation/tp-05-01

Étape 1 : Exécuter une commande au premier plan

Avec le compte de travail, créer le dossier du TP puis s’y placer :

Terminal Linux

# Créer le dossier indiqué pour les fichiers de travail du TP.
mkdir -p ~/devops-formation/tp-05-01

# Se placer dans le dossier requis pour les commandes suivantes.
cd ~/devops-formation/tp-05-01

Créez un conteneur Alpine qui affiche un message puis se termine.
Comparez ensuite la liste des conteneurs actifs et celle de tous les conteneurs, puis consultez son état et son code de sortie.

Premier plan : Sans -d, le client Docker reste attaché au conteneur et attend la fin de sa commande avant de rendre l’invite.
Ici, printf se termine presque immédiatement : cette attente est trop courte pour être visible.
Avec la boucle continue de l’étape 3, la différence sera visible : sans -d, les ticks défileraient dans ce terminal sans rendre l’invite ; avec -d, vous pourrez saisir une autre commande pendant que la boucle continue.

Terminal — PowerShell (Windows) ou Bash (Linux)

# Créer et démarrer un conteneur avec l’image, les ports et les montages indiqués.
docker run --name asd-tp01-simple --label formation.tp=m5-tp01 alpine:3.21.3 printf 'Bonjour depuis le conteneur\n'

# Lister les conteneurs pour contrôler leur état et les ports publiés.
docker ps --filter 'name=asd-tp01-simple'

# Lister les conteneurs pour contrôler leur état et les ports publiés.
docker ps -a --filter 'name=asd-tp01-simple'

# Lire les métadonnées de la ressource Docker pour vérifier son état ou sa configuration.
docker inspect --format '{{.State.Status}} / code={{.State.ExitCode}}' asd-tp01-simple

À observer : Le conteneur apparaît parmi les conteneurs arrêtés.
Son code de sortie indique si la commande a réussi.

Conclusion : Le conteneur exécute le programme demandé ; il s’arrête lorsque son processus principal se termine.

Si vos observations ne permettent pas de confirmer cette conclusion, comparez le résultat aux indications d’Observer et reprenez les commandes de cette manipulation. Relisez au besoin : Cycle de vie des conteneurs.

Interpréter : run crée et démarre un nouveau conteneur.
Quand sa commande principale se termine, il s’arrête ; il n’est pas supprimé automatiquement ici.
Un éventuel téléchargement initial est celui de l’image, pas une installation de service dans votre poste.

Conflict : le nom existe déjà

Ne pas supprimer arbitrairement ce nom.
Vérifier docker inspect --format '{{json .Config.Labels}}' asd-tp01-simple, son usage et son origine.
Le nettoyage ciblé en fin de TP concerne uniquement les ressources de cet exercice.

Étape 2 : Exécuter une commande dans un conteneur jetable

Relancez une commande courte dans un nouveau conteneur avec --rm pour supprimer automatiquement ce conteneur à la fin de son exécution.
Vérifiez ensuite qu’il n’apparaît plus dans la liste des conteneurs.

Terminal — PowerShell (Windows) ou Bash (Linux)

# Créer et démarrer un conteneur avec l’image, les ports et les montages indiqués.
docker run --rm --name asd-tp01-jetable --label formation.tp=m5-tp01 alpine:3.21.3 printf 'Conteneur temporaire\n'

# Lister les conteneurs pour contrôler leur état et les ports publiés.
docker ps -a --filter 'name=asd-tp01-jetable'

À observer : Le conteneur jetable a été supprimé après la fin de sa commande.

Conclusion : L’option --rm supprime le conteneur à sa sortie ; le résultat de la commande ne signifie pas qu’il reste en cours d’exécution.

Si vos observations ne permettent pas de confirmer cette conclusion, comparez le résultat aux indications d’Observer et reprenez les commandes de cette manipulation. Relisez au besoin : Cycle de vie des conteneurs.

Interpréter : --rm retire ce conteneur à sa fin ; il ne désinstalle pas Docker et ne supprime pas l’image téléchargée.
Nous n’utilisons aucun volume dans cet exercice.

Pourquoi docker logs ne retrouve plus le conteneur jetable ?

Il a été retiré : son nom et ses journaux Docker ne sont plus disponibles via docker logs.
Pour observer après la fin, utiliser le conteneur simple qui n’avait pas --rm, ou lire la sortie avant son retrait.

Étape 3 : Démarrer un processus en arrière-plan

Comprendre -d : L’option -d signifie detach : le client Docker rend immédiatement l’invite, tandis que le processus principal continue dans le conteneur.
Sans -d, avec cette même boucle, le client resterait attaché : vous verriez les ticks défiler et ne pourriez pas saisir la commande suivante dans ce terminal avant de vous détacher ou d’arrêter le processus.
Le détachement concerne la connexion du client, pas la durée de vie du conteneur.

Cette commande conserve un processus principal actif et écrit une ligne toutes les deux secondes.
Elle ne publie aucun port :

Terminal — PowerShell (Windows) ou Bash (Linux)

# Créer et démarrer un conteneur avec l’image, les ports et les montages indiqués.
docker run -d --name asd-tp01-service --label formation.tp=m5-tp01 alpine:3.21.3 sh -c '
trap "echo arret-demande; exit 0" TERM INT
n=0
while :; do
  printf "tick=%s\n" "$n"
  n=$((n + 1))
  sleep 2
done'

# Lister les conteneurs pour contrôler leur état et les ports publiés.
docker ps --filter 'name=asd-tp01-service'

À observer : run -d retourne un identifiant ; ps annonce Up.
Le terminal reste disponible tandis que le processus du conteneur continue.

Conclusion : Le mode détaché rend la main au terminal pendant que le processus du conteneur continue à fonctionner.

Si vos observations ne permettent pas de confirmer cette conclusion, comparez le résultat aux indications d’Observer et reprenez les commandes de cette manipulation. Relisez au besoin : Cycle de vie des conteneurs.

Interpréter : -d détache le client, pas la durée de vie du processus.
Le conteneur reste actif tant que son processus principal fonctionne.
Le trap permet de réagir à la demande d’arrêt.

Étape 4 : Lire puis suivre les journaux du conteneur

Affichez les dernières lignes écrites par le processus du conteneur, avec leurs horodatages, puis suivez les nouvelles lignes en direct.

Terminal — PowerShell (Windows) ou Bash (Linux)

# Lire les sorties standard et d’erreur du conteneur pour observer son exécution.
docker logs --tail 5 --timestamps asd-tp01-service

# Suivre les nouvelles sorties standard et d’erreur du conteneur.
docker logs --follow --tail 2 asd-tp01-service

À observer : des lignes tick=0, tick=1, etc.
avec des horodatages dans le premier affichage.
Leur nombre dépend du temps écoulé.
Le suivi ajoute les nouvelles lignes sans rendre l’invite.

Appuyez sur Ctrl+C pour interrompre le suivi, puis vérifiez avec docker ps que le conteneur fonctionne toujours.

Terminal — PowerShell (Windows) ou Bash (Linux)

# Lister les conteneurs pour contrôler leur état et les ports publiés.
docker ps --filter 'name=asd-tp01-service'

À observer : le conteneur est toujours Up.
Ctrl+C a arrêté le client qui suivait les logs ; ici, il n’a pas arrêté le service.
docker logs lit les sorties standard et d’erreur du processus du conteneur, pas tous les fichiers du système.

Conclusion : docker logs affiche les sorties standard et d’erreur ; le suivi permet d’observer les nouveaux messages sans relancer la commande. C'est pourquoi nous devriez voir des lignes tick=0, tick=1, etc.

Si vos observations ne permettent pas de confirmer cette conclusion, comparez le résultat aux indications d’Observer et reprenez les commandes de cette manipulation. Relisez au besoin : Cycle de vie des conteneurs.

Étape 5 : Exécuter une commande puis ouvrir un shell dans le conteneur

Depuis le terminal de votre poste, créez le fichier témoin /tmp/temoin dans le conteneur avec docker exec, puis ouvrez un shell interactif dans ce même conteneur.

Terminal — PowerShell (Windows) ou Bash (Linux)

# Contrôler les fichiers du conteneur pour vérifier la présence ou la persistance du témoin.
docker exec asd-tp01-service sh -c 'printf "cree depuis exec\n" > /tmp/temoin; cat /tmp/temoin'

# Ouvrir un shell dans le conteneur déjà démarré.
docker exec -it asd-tp01-service sh

À observer : La première commande affiche le témoin ; la seconde ouvre une invite dans le conteneur.
Dans ce shell, identifiez l’utilisateur, consultez le répertoire courant et le fichier témoin, puis quittez avec exit.

# Vérifier l’identité, les groupes ou l’existence du compte ciblé.
whoami

# Afficher le dossier courant.
pwd

# Lire le fichier pour vérifier son contenu.
cat /tmp/temoin

# Quitter la session courante pour revenir au terminal précédent.
exit

De retour dans le terminal du poste, vérifiez l’état du conteneur et consultez ses journaux.

Terminal — PowerShell (Windows) ou Bash (Linux)

# Lister les conteneurs pour contrôler leur état et les ports publiés.
docker ps --filter 'name=asd-tp01-service'

# Lire les sorties standard et d’erreur du conteneur pour observer son exécution.
docker logs --tail 3 asd-tp01-service

À observer : la session interactive est fermée, mais le processus principal continue et le conteneur reste Up.
Les logs montrent les ticks ; la sortie de cat lancée via exec a été envoyée à votre terminal et ne devient pas automatiquement une ligne des logs du processus principal.

Conclusion : docker exec lance un processus supplémentaire dans un conteneur déjà démarré ; ouvrir un shell ne crée pas un nouveau conteneur.

Si vos observations ne permettent pas de confirmer cette conclusion, comparez le résultat aux indications d’Observer et reprenez les commandes de cette manipulation. Relisez au besoin : Cycle de vie des conteneurs.

bash introuvable, terminal non interactif ou conteneur arrêté

Alpine fournit sh ; ce TP utilise donc docker exec -it ... sh, pas bash.
Exécutez docker exec -it dans un terminal Linux interactif.
exec exige un conteneur actif ; si celui-ci est Exited, vérifier ses logs et son état avant de le redémarrer.

Étape 6 : Arrêter puis redémarrer le même conteneur

Arrêtez le conteneur, consultez son état et ses journaux, puis redémarrez ce même conteneur.
Relisez ensuite /tmp/temoin pour vérifier que son fichier a été conservé.

Terminal — PowerShell (Windows) ou Bash (Linux)

# Arrêter le conteneur sans le supprimer ; ses fichiers locaux restent présents.
docker stop asd-tp01-service

# Lire les métadonnées de la ressource Docker pour vérifier son état ou sa configuration.
docker inspect --format '{{.State.Status}} / code={{.State.ExitCode}}' asd-tp01-service

# Lire les sorties standard et d’erreur du conteneur pour observer son exécution.
docker logs --tail 3 asd-tp01-service

# Démarrer le processus d’un conteneur déjà créé.
docker start asd-tp01-service

# Contrôler les fichiers du conteneur pour vérifier la présence ou la persistance du témoin.
docker exec asd-tp01-service cat /tmp/temoin

À observer : Le compteur repart à zéro au redémarrage du processus.
Le fichier /tmp/temoin reste présent dans le même conteneur.

Conclusion : Redémarrer le même conteneur relance son processus principal mais conserve sa couche inscriptible Un compteur du processus peut repartir à zéro sans supprimer le fichier témoin. En effet, le fichier /tmp/temoin est encore présent dans le même conteneur.

Si vos observations ne permettent pas de confirmer cette conclusion, comparez le résultat aux indications d’Observer et reprenez les commandes de cette manipulation. Relisez au besoin : Cycle de vie des conteneurs.

Interpréter : stop/start réutilise le même conteneur et sa couche écrivable.
La boucle principale recommence son compteur, mais le fichier créé par exec reste.
Le traitement du signal peut prendre le temps de la pause sleep.

Étape 7 : Supprimer le conteneur et comparer avec une nouvelle exécution

Arrêtez puis supprimez le conteneur précédent.
Créez un nouveau conteneur à partir de la même image et vérifiez si /tmp/temoin y existe.

Terminal — PowerShell (Windows) ou Bash (Linux)

# Arrêter le conteneur sans le supprimer ; ses fichiers locaux restent présents.
docker stop asd-tp01-service

# Supprimer les conteneurs nommés ; leur couche inscriptible sera perdue.
docker rm asd-tp01-service

# Créer et démarrer un conteneur avec l’image, les ports et les montages indiqués.
docker run --rm --name asd-tp01-verification --label formation.tp=m5-tp01 alpine:3.21.3 sh -c 'if test -f /tmp/temoin; then cat /tmp/temoin; else echo "temoin absent dans le nouveau conteneur"; fi'

À observer : Le nouveau conteneur ne contient pas le fichier créé dans la couche inscriptible du précédent.

Conclusion : Une nouvelle exécution crée un autre conteneur les fichiers de la couche inscriptible du précédent ne sont pas transférés automatiquement.

Si vos observations ne permettent pas de confirmer cette conclusion, comparez le résultat aux indications d’Observer et reprenez les commandes de cette manipulation. Relisez au besoin : Cycle de vie des conteneurs.

Interpréter : une nouvelle exécution run repart de l’image ; elle ne récupère pas la couche écrivable du conteneur supprimé.
Les montages persistants seront abordés dans les TP de stockage.

Vérification finale

  • Expliquer la différence entre run, start et exec.
  • Constater la disparition du conteneur lancé avec --rm.
  • Suivre les logs puis sortir du suivi sans arrêter le service.
  • Constater la conservation d’un fichier après stop/start, puis sa perte après rm et un nouveau run.

Retenir

run crée et démarre ; --rm retire le conteneur à sa fin ; exec ajoute une commande dans un conteneur actif ; logs lit ses sorties ; stop/start conserve le conteneur ; rm retire sa couche écrivable.

Documentation des commandes

run et --rm · exec · logs.

Nettoyage

Dépendances

Configuration pour Linux

Linux : utiliser le même terminal et le même contexte Docker Engine que pour les étapes.

En fin de parcours normal, seul asd-tp01-simple reste arrêté.
Si le TP a été interrompu, afficher les ressources du laboratoire, puis arrêter les conteneurs encore actifs portant son label :

docker ps -a --filter label=formation.tp=m5-tp01 --format 'table {{.Names}}\t{{.Status}}'
for name in asd-tp01-simple asd-tp01-jetable asd-tp01-service asd-tp01-verification; do
  if docker container inspect "$name" >/dev/null 2>&1; then
    label=$(docker inspect --format '{{index .Config.Labels "formation.tp"}}' "$name")
    if [ "$label" != m5-tp01 ]; then
      printf 'Conserver %s : label du TP absent\n' "$name"
      continue
    fi
    if [ "$(docker inspect --format '{{.State.Running}}' "$name")" = true ]; then
      docker stop "$name"
    fi
    docker rm "$name"
  fi
done
docker ps -a --filter label=formation.tp=m5-tp01

À observer : le dernier tableau est vide.
Les commandes ciblent seulement les quatre noms du laboratoire et vérifient leur label, y compris après interruption ; elles ne suppriment aucun autre conteneur et ne lancent aucun prune.
Vérifier que les ressources portant ce label appartiennent bien à votre essai.

Conservez l’image Alpine pour les TP suivants.
Si elle n’est plus nécessaire, vous pouvez la supprimer avec docker image rm alpine:3.21.3, sans --force.
Un refus peut signaler qu’un autre conteneur utilise encore cette image.

Prérequis

Configuration pour Linux

Conserver student, devops et l’environnement pour les TP suivants.
Le retrait complet reste facultatif, après nettoyage des dépendances et sauvegarde des travaux.

Guide : Préparer Linux pour les TP

Conserver le moteur Docker pour la suite.

Guide : Préparer Docker pour les TP

exit quitte la session student et revient au compte initial si vous avez utilisé su - student.
Le système Linux du poste reste installé.