Quatre minutes pour une ligne changée
Un Dockerfile est un fichier texte qui décrit, étape par étape, comment construire une image. L’ordre de ses étapes décide du temps de construction.
Une équipe change une ligne du code d’une boutique. La construction dure quatre minutes, car elle retélécharge toutes les bibliothèques.
Une autre équipe change la même ligne et attend une seconde. Les deux ont écrit un fichier de construction. Elles ont écrit les étapes dans un ordre différent.
À la fin de cette leçon
Remarque
Je peux écrire un Dockerfile et dire quelles étapes sont refaites après un changement.
Mots-clés
| Mot | Ce que ça veut dire |
|---|---|
| Dockerfile | un fichier texte d’étapes qui construit une image |
| Image de base | l’image dont une construction part |
| Couche (layer) | le résultat gardé d’une étape de construction |
| Cache | des couches gardées qu’une construction réutilise |
| Construire (build) | fabriquer une image en exécutant les étapes |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Ce que le labo ne peut pas faire
Remarque
Le docker du labo refuse de construire ou de télécharger une image : une construction lance des étapes avec des droits sur la machine. Nous avons construit ces Dockerfile sur notre machine. Vous les lisez, regardez ce qu’une image laisse dans un conteneur, et vérifiez votre fichier dans le devoir. Pour construire vraiment, utilisez votre machine.
Un Dockerfile est une liste d’étapes
Chaque ligne commence par un mot d’instruction. FROM nomme l’image de base. COPY apporte des fichiers. RUN lance une commande pendant la construction. CMD dit quoi lancer quand un conteneur démarre.
Docker lit les lignes depuis le haut. Voici une petite boutique écrite ainsi.
Un Dockerfile pour une petite boutique Python
FROM python:3.12-alpine
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
CMD ["python", "app.py"]
Le dossier de départ, réglé par WORKDIR
docker inspect --format '{{.Config.WorkingDir}}' cacheAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Le signal qui arrête web, réglé par STOPSIGNAL
docker inspect --format '{{.Config.StopSignal}}' webAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Exemple travaillé : ce que chaque instruction laisse
| Instruction | Ce qu’elle fait à la construction | Où on la revoit ensuite |
|---|---|---|
| FROM | part d’une image de base | Config.Image nomme l’image |
| WORKDIR | règle le dossier des étapes suivantes | Config.WorkingDir, /data pour cache |
| EXPOSE | dit quelle porte le programme utilise | Config.ExposedPorts, 80/tcp pour web |
| STOPSIGNAL | dit comment demander l’arrêt du programme | Config.StopSignal, SIGQUIT pour web |
| COPY et RUN | ajoutent des fichiers et lancent des commandes | une nouvelle couche chacun |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Chaque étape fait une couche
Une construction garde le résultat de chaque étape comme une couche. Les couches sont empilées, et une image est toute la pile. Une couche ne change plus une fois faite.
Un conteneur ajoute une fine couche au-dessus, où il écrit. docker diff liste ce qu’il y a dans cette couche du dessus.
Exemple travaillé : les couches de l’image
| Étape | Taille sur notre machine de test |
|---|---|
| L’image de base, python:3.12-alpine | environ 48 Mo pour sa plus grosse couche |
| WORKDIR /app | 8 ko |
| COPY requirements.txt . | 12 ko |
| RUN pip install ... | 10,6 Mo |
| COPY app.py . | 12 ko |
| CMD ["python", "app.py"] | 0 o |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Écrire un fichier dans web
docker exec web touch /tmp/layer-demo.txtAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Le retrouver dans la couche du dessus
docker diff web | grep layer-demoAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Le cache réutilise une couche inchangée
Avant de lancer une étape, Docker pose une question. Est-ce la même étape, avec les mêmes fichiers que la dernière fois, et tout ce qui est au-dessus était-il pareil ? Si oui, il réutilise la couche gardée. C’est le cache.
La première étape qui diffère est refaite. Toutes les suivantes aussi. Mettez en haut ce qui change le moins.
Ordre 1 : tout copier d’abord
FROM python:3.12-alpine
WORKDIR /app
COPY . .
RUN pip install --no-cache-dir -r requirements.txt
CMD ["python", "app.py"]
Exemple travaillé : modifier app.py, puis reconstruire
| Étape | Ordre 1 | Ordre 2 (le premier Dockerfile ci-dessus) |
|---|---|---|
| WORKDIR /app | en cache | en cache |
| COPY requirements.txt . | absente dans cet ordre | en cache |
| COPY . . | refaite | absente dans cet ordre |
| RUN pip install ... | refaite, 11 secondes | en cache |
| COPY app.py . | absente dans cet ordre | refaite, moins d’une seconde |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Une erreur fréquente
Attention
On croit souvent que Docker ne refait que la ligne qu’on a modifiée. Il refait cette étape et toutes celles d’après. Copiez d’abord le fichier qui liste vos bibliothèques et installez-les, puis copiez votre propre code. L’étape lente reste alors en cache.
Pour aller plus loin
Écrivez le Dockerfile d’un petit site à vous. Partez de nginx:1.27-alpine, copiez un seul index.html dans /usr/share/nginx/html et n’ajoutez rien d’autre.
Sur une machine avec Docker, construisez-le deux fois. La seconde construction doit afficher CACHED à chaque étape.