Skip to content

TP 1.5 — Construire ses propres images Docker

BTS SIO SISR 1ère année Durée : 2 heures Docker + Debian

Contexte

Au TP 1, vous avez utilisé des images Docker Hub toutes prêtes (httpd, hello-world). Mais d'où viennent ces images ? Quelqu'un les a construites. TechServices veut maintenant standardiser ses déploiements : plutôt que de télécharger une image et de la modifier à la main à chaque fois, l'équipe infrastructure va construire ses propres images sur mesure — intégrant directement les fichiers de l'entreprise, distribuables à n'importe quel membre de l'équipe sans manipulation supplémentaire.


Mission 1 — Anatomie d'un Dockerfile

Tâche 1.1 — Créer un dossier de travail

bash
mkdir ~/tp-dockerfile && cd ~/tp-dockerfile

Travaillez toujours dans un dossier dédié : le dossier courant devient le contexte de build — les fichiers que Docker pourra copier dans l'image.

Tâche 1.2 — Écrire le premier Dockerfile

bash
nano Dockerfile
dockerfile
FROM httpd:latest
CMD ["/bin/sh", "-c", "echo 'Serveur Apache en cours de démarrage...' && httpd-foreground"]

Décryptage

FROM httpd:latest — point de départ. On repart de l'image httpd déjà vue au TP 1 : Apache y est déjà installé et configuré.

CMD — la commande qui s'exécutera dans le conteneur au moment du docker run. Ici : on affiche un message de démarrage, puis on lance Apache.

Tâche 1.3 — Construire l'image

bash
docker build -t techservices-web:1.0 .

Décryptage de la commande

  • docker build — construit une image à partir d'un Dockerfile
  • -t techservices-web:1.0 — donne un nom (techservices-web) et un tag (1.0) à l'image
  • . — contexte de build : Docker cherche le Dockerfile dans le dossier courant

Tâche 1.4 — Comparer avec l'image d'origine

bash
docker images

📸 Capture 1

Sortie de docker imagestechservices-web apparaît dans la liste à côté de httpd.

Les deux images sont distinctes, mais presque identiques pour l'instant — la différence viendra quand on y intégrera nos propres fichiers.

Tâche 1.5 — Lancer un conteneur et observer CMD en action

bash
docker run -d --name test-web -p 8080:80 techservices-web:1.0
docker logs test-web

Le message "Serveur Apache en cours de démarrage..." est visible dans les logs — preuve que CMD s'exécute dans le conteneur, au moment du docker run, pas au moment du build.

📸 Capture 2

Sortie de docker logs test-web — le message de démarrage est visible avant les logs Apache.


Mission 2 — Intégrer ses fichiers avec COPY

Tâche 2.1 — Créer une page HTML

Dans votre dossier ~/tp-dockerfile, créez le fichier index.html :

bash
nano index.html
html
<!DOCTYPE html>
<html>
<head>
  <title>TechServices</title>
</head>
<body>
  <h1>TechServices</h1>
  <p>Portail interne — version 1.0</p>
</body>
</html>

Tâche 2.2 — Modifier le Dockerfile pour intégrer le fichier

bash
nano Dockerfile
dockerfile
FROM httpd:latest
COPY index.html /usr/local/apache2/htdocs/index.html
CMD ["/bin/sh", "-c", "echo 'Serveur Apache en cours de démarrage...' && httpd-foreground"]

COPY : source → destination

  • Source : index.html dans votre dossier de build (sur la machine hôte)
  • Destination : /usr/local/apache2/htdocs/index.html dans l'image

Le fichier sera présent dans toutes les instances de cette image, sans aucune manipulation manuelle.

Tâche 2.3 — Reconstruire et tester

bash
docker build -t techservices-web:1.0 .
docker rm -f test-web
docker run -d --name test-web -p 8080:80 techservices-web:1.0

Accédez à http://[IP-de-la-VM]:8080 depuis votre navigateur.

📸 Capture 3

Page HTML personnalisée TechServices affichée dans le navigateur.

Tâche 2.4 — Vérifier que c'est reproductible

Supprimez le conteneur et créez-en un nouveau depuis la même image :

bash
docker rm -f test-web
docker run -d --name test-web2 -p 8080:80 techservices-web:1.0

Accédez à nouveau à http://[IP-de-la-VM]:8080.

📸 Capture 4

Page personnalisée toujours présente après suppression et recréation du conteneur — sans aucune modification manuelle.

Le déclic

Au TP 1, on modifiait index.html avec docker exec ... echo > ... — et la modification disparaissait à la suppression du conteneur.

Ici, index.html est intégré dans l'image. N'importe qui qui lance techservices-web:1.0 obtient la même page. C'est ça, une image.


Mission 3 — Exécuter des commandes au build avec RUN

Tâche 3.1 — Ajouter une commande RUN

bash
nano Dockerfile
dockerfile
FROM httpd:latest
RUN echo "Image construite par TechServices" > /usr/local/apache2/htdocs/info.txt
COPY index.html /usr/local/apache2/htdocs/index.html
CMD ["/bin/sh", "-c", "echo 'Serveur Apache en cours de démarrage...' && httpd-foreground"]

Tâche 3.2 — Observer les couches lors du build

bash
docker build -t techservices-web:1.0 .

La sortie affiche les étapes numérotées. Chaque instruction du Dockerfile est une étape distincte — et chaque RUN crée une nouvelle couche dans l'image.

📸 Capture 5

Sortie de docker build — les étapes sont numérotées, le RUN apparaît comme une étape distincte.

Tâche 3.3 — Vérifier que RUN s'est exécuté au build

bash
docker rm -f test-web2
docker run -d --name test-web3 -p 8080:80 techservices-web:1.0
docker exec test-web3 cat /usr/local/apache2/htdocs/info.txt

Le fichier info.txt existe — il a été créé au moment du build, pas au démarrage du conteneur. À chaque docker run, le résultat est déjà là dans l'image.

📸 Capture 6

Contenu de info.txt affiché depuis l'intérieur du conteneur : "Image construite par TechServices".

Tâche 3.4 — Observer les couches de l'image

bash
docker history techservices-web:1.0

Chaque instruction du Dockerfile correspond à une couche. Retrouvez-y votre RUN et votre COPY.

📸 Capture 7

Sortie de docker history — couches listées avec leur taille et la commande qui les a créées.

Relier avec le TP 1

Au TP 1, lors du docker pull httpd, vous avez vu des lignes Pull complete s'afficher une par une. Ce sont les couches de l'image qui se téléchargent séparément. Chaque RUN dans un Dockerfile produit une couche — et ces couches sont réutilisables entre images.


Questions de réflexion

Répondez à ces questions dans votre tête ou à l'oral avec votre voisin — elles seront à la base de la discussion en fin de séance :

  1. Quelle différence concrète avez-vous observée entre modifier un conteneur avec docker exec (TP 1) et intégrer un fichier avec COPY ?
  2. Pourquoi RUN s'exécute-t-il au moment du build et non au démarrage du conteneur ?
  3. Si vous donnez votre image techservices-web:1.0 à un collègue, que devra-t-il faire pour lancer le serveur avec votre page personnalisée ?

Récapitulatif des instructions Dockerfile

InstructionQuand s'exécute-t-elle ?Rôle
FROMBuildImage de base (point de départ)
RUNBuildExécuter une commande et créer une couche
COPYBuildCopier des fichiers de l'hôte vers l'image
CMDRuntimeCommande par défaut au démarrage du conteneur