Construire efficacement
- Leçon 5
- 50 min
- Module 2 : Construire l'image de l'application
Leçon 5 sur 15 · L'essentiel de Docker et du nuage pour les développeurs en IAConstruire efficacement
1. Comprendre les conteneurs
2. Construire l'image de l'application
3. Réseau, configuration et persistance
4. Les services de base du nuage
5. Déployer et nettoyer
Ce que vous saurez faire
Accélérez chaque reconstruction, n’envoyez aucun fichier secret ou volumineux à la construction et produisez la même image chaque fois. Après un changement de code, la reconstruction prend moins d’une seconde au lieu de 15. L’image est aussi 54 Mo plus petite.
Avant de commencerCe qu’il faut savoir et avoir sous la main
Ce que vous devez savoir
- Les couches et
docker history, dans Images et conteneurs en cours d’exécution : ce que contient une image. - Les six instructions et la sortie de construction, dans L’essentiel du Dockerfile : les six instructions et Construire l’image.
Ce qu’il vous faut sur votre ordinateur
- Le
Dockerfile, dans L’essentiel du Dockerfile : écrire le Dockerfile. requirements-run.txt, dans L’essentiel du Dockerfile : créer requirements-run.txt dans un conteneur.- L’image
ticket-api:1.0.0, dans L’essentiel du Dockerfile : construire l’image. - Si votre projet manque ou ne fonctionne plus, copiez le dernier instantané du cours sur les API,
end-of-m07. Faites ensuite l’exercice guidé de L’essentiel du Dockerfile. Utiliser un instantané présente les étapes.
Testé avec Docker Desktop 4.81.0 (Docker Engine 29.6.1) sur macOS, avec une puce Apple. Les étapes pour Windows et Linux n’ont pas été testées. Les temps de construction dépendent de votre ordinateur et de votre réseau.
Modifier un fichier et reconstruire
Section intitulée « Modifier un fichier et reconstruire »Amira ajoute un commentaire dans ticket_api/models.py, au-dessus de la ligne Category = Literal[...] :
# The categories that the classifier can return.Category = Literal["billing", "login", "shipping", "account", "other"]Elle reconstruit ensuite l’image avec la même commande.
Prédisez : la première construction a pris 13,4 secondes, dont 10,4 pour pip install. Lesquelles des six étapes afficheront maintenant CACHED (en cache)? Combien de temps prendra la construction?
docker build -t ticket-api:1.0.0 .La sortie (abrégée) :
[+] Building 0.6s (11/11) FINISHED docker:desktop-linux ... => [1/6] FROM docker.io/library/python:3.14-slim@sha256:f85c5697265c178c 0.0s ... => => transferring context: 3.77kB 0.0s => CACHED [2/6] WORKDIR /app 0.0s => CACHED [3/6] COPY requirements-run.txt . 0.0s => CACHED [4/6] RUN pip install -r requirements-run.txt 0.0s => CACHED [5/6] COPY pyproject.toml . 0.0s => [6/6] COPY ticket_api ./ticket_api 0.0s ...0,6 seconde. Les étapes 2 à 5 affichent CACHED. Seule l’étape 6, qui copie le dossier modifié, s’est exécutée de nouveau. Docker n’a installé aucun paquet.
Le cache des couches
Section intitulée « Le cache des couches »Chaque étape d’une construction crée une couche. Docker conserve les couches créées dans son cache de construction. Avant d’exécuter une étape, il vérifie deux choses :
- L’instruction est-elle la même que la dernière fois?
- Pour
COPY: les fichiers sont-ils identiques, octet par octet? Docker compare une somme de contrôle de leur contenu, pas leur date.
Si les deux sont identiques et que l’étape précédente vient aussi du cache, Docker reprend l’ancienne couche : CACHED. Dès qu’une étape diffère, le cache cesse d’aider. Cette étape s’exécute, et toutes les étapes suivantes s’exécutent aussi, car chaque couche repose sur la précédente.
Voici donc la règle pour l’ordre d’un Dockerfile : ce qui change rarement vient en premier; ce qui change souvent vient en dernier. L’image de base change quelques fois par année. La liste des paquets change quand vous ajoutez un paquet. Le code change chaque jour. C’est l’ordre du Dockerfile d’Amira.
Retirez maintenant le commentaire de models.py et reconstruisez. Prédisez d’abord : l’étape 6 s’exécute-t-elle de nouveau?
La sortie (abrégée) :
[+] Building 0.2s (11/11) FINISHED docker:desktop-linux ... => CACHED [5/6] COPY pyproject.toml . 0.0s => CACHED [6/6] COPY ticket_api ./ticket_api 0.0sChaque étape affiche CACHED. Les fichiers sont de nouveau identiques à ceux d’une construction précédente, et Docker possède encore cette couche.
Description textuelle du diagramme
Deux colonnes montrent le même changement, une ligne dans ticket_api/models.py, construit avec deux ordres du Dockerfile.
Le bon ordre compte six étapes. [1/6] FROM python:3.14-slim utilise la même image. [2/6] WORKDIR /app, [3/6] COPY requirements-run.txt ., [4/6] RUN pip install et [5/6] COPY pyproject.toml . sont en cache. Une ligne pointillée précède [6/6] COPY ticket_api ./ticket_api, la première étape dont l’entrée a changé. Elle s’exécute en 0,0 s. La construction complète prend 0,4 s.
Le mauvais ordre compte quatre étapes. [1/4] FROM utilise la même image, et [2/4] WORKDIR /app est en cache. La ligne pointillée précède [3/4] COPY . ., qui copie tous les fichiers, y compris celui qui a changé. Cette étape s’exécute en 0,9 s. [4/4] RUN pip install vient ensuite et s’exécute donc aussi, en 11,4 s. La construction complète prend 16,7 s.
Explorer : quelles étapes s’exécutent de nouveau?
Section intitulée « Explorer : quelles étapes s’exécutent de nouveau? »Chaque nombre dans l’explorateur est une mesure réelle sur l’ordinateur de test de cette leçon. C’est la médiane de trois constructions pour chaque changement. Vos temps seront différents, mais la répartition entre CACHED et RUN (exécution) reste la même sur tous les ordinateurs.
Explorer
Cache des couches : quelles étapes s'exécutent de nouveau après un changement?
Prédisez d’abord : Vous modifiez un fichier et reconstruisez. Quel changement relance pip install : models.py, requirements-run.txt, pyproject.toml, README.md ou l'image de base?
- Étapes réexécutées
- 1 sur 6
- pip install
- CACHED
- Construction complète
- 0,4 s
Changement : une ligne ajoutée à ticket_api/models.py. Avec le bon ordre, 1 étape sur 6 est réexécutée et la construction prend 0,4 s. [6/6] COPY ticket_api ./ticket_api est la première étape dont l’entrée a changé. Elle est réexécutée, comme chaque étape qui la suit. pip install vient du cache.
- CACHED : tiré du cache
- RUN : réexécutée
| Étape | Instruction | Résultat | Temps |
|---|---|---|---|
| [1/6] | FROM python:3.14-slim | même image | - |
| [2/6] | WORKDIR /app | CACHED | - |
| [3/6] | COPY requirements-run.txt . | CACHED | - |
| [4/6] | RUN pip install -r requirements-run.txt | CACHED | - |
| [5/6] | COPY pyproject.toml . | CACHED | - |
| [6/6] | COPY ticket_api ./ticket_api | RUN | 0,0 s |
Description textuelle de l’explorateur
L’explorateur montre les six étapes de construction du Dockerfile d’Amira après un changement, avec leur résultat et leur temps mesuré. L’état initial est un changement d’une ligne dans ticket_api/models.py. Seule [6/6] COPY ticket_api ./ticket_api s’exécute, et la construction prend 0,4 s.
Les autres changements : une ligne dans requirements-run.txt fait exécuter les étapes 3 à 6. pip install prend 12,8 s sur une construction de 15,8 s. Une ligne dans pyproject.toml fait exécuter les étapes 5 et 6, en 0,4 s. Une ligne dans README.md ne change rien pour Docker, car aucune étape ne copie README.md. Toutes les étapes après FROM sont en cache, pour un temps de 0,3 s. Une nouvelle image de base (FROM python:3.13-slim) fait exécuter toutes les étapes. pip install prend 13,5 s sur une construction de 16,3 s.
Et si l’ordre est mauvais?
Section intitulée « Et si l’ordre est mauvais? »Beaucoup de Dockerfiles sur Internet utilisent un ordre plus court : copier le dossier complet, puis installer.
FROM python:3.14-slimWORKDIR /appCOPY . .RUN pip install -r requirements-run.txtEXPOSE 8000CMD ["fastapi", "run", "--host", "0.0.0.0", "--port", "8000"]Cela fonctionne, avec deux lignes de moins. Amira l’a essayé dans une copie du projet pour le mesurer. Passez l’explorateur au mauvais ordre, puis essayez chaque fichier de nouveau.
Explorer
Cache des couches : le bon ordre et le mauvais ordre
Prédisez d’abord : Dans le mauvais ordre, COPY . . précède pip install. Lesquels des cinq changements permettent encore de récupérer pip install du cache?
- Étapes réexécutées
- 2 sur 4
- pip install
- réexécuté, 11,4 s
- Construction complète
- 16,7 s
Changement : une ligne ajoutée à ticket_api/models.py. Avec le mauvais ordre, 2 étapes sur 4 sont réexécutées et la construction prend 16,7 s. [3/4] COPY . . est la première étape dont l’entrée a changé. Elle est réexécutée, comme chaque étape qui la suit. pip install est réexécuté : 11,4 s sur 16,7 s.
- CACHED : tiré du cache
- RUN : réexécutée
| Étape | Instruction | Résultat | Temps |
|---|---|---|---|
| [1/4] | FROM python:3.14-slim | même image | - |
| [2/4] | WORKDIR /app | CACHED | - |
| [3/4] | COPY . . | RUN | 0,9 s |
| [4/4] | RUN pip install -r requirements-run.txt | RUN | 11,4 s |
Description textuelle de l’explorateur
L’explorateur commence dans le mauvais ordre, avec le changement d’une ligne dans ticket_api/models.py. [3/4] COPY . . s’exécute (0,9 s), tout comme [4/4] RUN pip install (11,4 s). La construction prend 16,7 s, contre 0,4 s dans le bon ordre.
Dans le mauvais ordre, chaque changement relance pip install. La construction complète prend 16,7 s pour models.py et 16,0 s pour requirements-run.txt. Elle prend 20,0 s pour pyproject.toml, 21,2 s pour README.md et 29,0 s pour l’image de base. COPY . . copie tous les fichiers du dossier. Ainsi, même un changement dans README.md, que l’application n’utilise pas, réinstalle les 50 paquets. Dans le bon ordre, seul un changement dans requirements-run.txt ou dans l’image de base relance pip install.
Le mauvais ordre coûte environ 16 secondes par changement de code. Une équipe qui construit 50 fois par jour attend plus de 13 minutes chaque jour. Chaque construction télécharge aussi les mêmes paquets de nouveau.
Le contexte de construction et .dockerignore
Section intitulée « Le contexte de construction et .dockerignore »Le . à la fin de docker build -t ticket-api:1.0.0 . est le contexte de construction. C’est le dossier dont Docker peut utiliser les fichiers dans COPY. Avant la construction, la commande docker envoie les fichiers du contexte au constructeur, la partie de Docker qui exécute les étapes.
Regardez la ligne transferring context (transfert du contexte) dans la sortie de construction. Amira l’a mesurée dans de nouvelles copies du projet contenant .venv, un dossier .git et un fichier .env avec une clé. La plupart des projets ont ces éléments :
| Dockerfile | .dockerignore |
transferring context |
|---|---|---|
Mauvais ordre, COPY . . |
aucun | 84.87MB (4,1 s) |
Bon ordre, trois lignes COPY |
aucun | 47.05kB |
| L’un ou l’autre | la liste d’autorisation ci-dessous | 16.86kB |
Le constructeur demande seulement les fichiers nécessaires aux lignes COPY. Avec COPY . ., cela comprend tous les fichiers : l’environnement virtuel, l’historique Git et .env. Tout entre ensuite dans l’image. Amira a vérifié l’image construite dans le mauvais ordre :
docker run --rm ticket-api-poor ls -a /appLa sortie :
....env.git.gitignore.pytest_cache.venvDockerfileREADME.mdbrowser-testcontractpostmanpyproject.tomlrequestsrequirements-lock.txtrequirements-run.txtrequirements.txtteststicket_apiLa clé dans .env est maintenant dans l’image. Toute personne qui obtient l’image peut la lire. Cette image faisait aussi 492 Mo, contre 363 Mo pour le bon ordre.
Le bon ordre a envoyé 47,05 ko, même si le Dockerfile d’Amira n’a aucune ligne COPY . .. Le dossier ticket_api contient des dossiers __pycache__ provenant des tests du cours sur les API. Ils sont entrés dans l’image. Et un jour, quelqu’un pourrait ajouter COPY . . au Dockerfile.
Un fichier .dockerignore empêche cela. Il énumère les fichiers que la construction ne doit jamais voir. Créez-le dans le dossier du projet :
# Send only what the image needs. Everything else stays out of the build,# including .env, secrets/, .venv and .git.*!requirements-run.txt!pyproject.toml!ticket_api/**/__pycache__/C’est une liste d’autorisation. La ligne * ignore tout. Chaque ligne avec ! autorise de nouveau un élément. La dernière ligne exclut de nouveau les dossiers __pycache__. L’autre méthode est une liste d’exclusion (.env, .venv, .git, …). Vous devez la modifier pour chaque nouveau fichier secret, et personne n’y pense. Une liste d’autorisation ne peut rien oublier : un nouveau fichier reste exclu jusqu’à ce que vous l’autorisiez.
Description textuelle du diagramme
À gauche, le dossier du projet est divisé en deux groupes. Le groupe « Restent sur votre ordinateur » contient .venv/ (la majeure partie des 84,87 Mo), .git/ et .env avec la clé d’API. Il contient aussi .pytest_cache/, tests/, postman/, requests/, contract/, browser-test/, README.md, requirements.txt, requirements-lock.txt et les dossiers __pycache__/. Une ligne pointillée indique qu’ils n’atteignent jamais le constructeur et ne peuvent donc pas être copiés dans l’image. Le groupe « Envoyés à Docker » contient requirements-run.txt, pyproject.toml et ticket_api/. Une flèche les fait passer par .dockerignore, avec ses règles *, !requirements-run.txt, !pyproject.toml, !ticket_api/ et **/__pycache__/. Ces règles ignorent tout, puis autorisent trois éléments. Ils deviennent le contexte de construction, de 16,86 ko, et docker build peut copier seulement ces fichiers.
Fixer les versions
Section intitulée « Fixer les versions »Fixer une version signifie choisir une version exacte. Ainsi, une construction le mois prochain donne la même image qu’aujourd’hui. requirements-run.txt fixe déjà la version de chaque paquet. L’image de base n’est pas encore fixée : python:3.14-slim est une étiquette qui change. Aujourd’hui, elle correspond à Python 3.14.8 sur Debian 13. Après la prochaine version de Python, la même étiquette donnera une autre image.
L’image Python possède des étiquettes plus précises. python:3.14.8-slim-trixie indique la version de Python (3.14.8), la variante (slim) et la version de Debian (13, appelée trixie). Utilisez-la dans le Dockerfile :
FROM python:3.14-slimFROM python:3.14.8-slim-trixieMême une étiquette exacte peut changer. Les responsables de l’image peuvent publier une nouvelle construction sous la même étiquette, par exemple avec un correctif de sécurité. La façon la plus stricte de fixer l’image est son empreinte : une somme de contrôle de son contenu. Affichez-la :
docker image inspect python:3.14.8-slim-trixie --format '{{index .RepoDigests 0}}'La sortie :
python@sha256:f85c5697265c178cc6887276c55fe16cf3d14ca35c3df6a5eab3b360534a55d2Vous pouvez écrire FROM python:3.14.8-slim-trixie@sha256:f85c… avec l’empreinte complète. La construction utilise alors toujours exactement ces octets. Le coût : l’image ne reçoit aucun correctif de sécurité tant que vous ne changez pas l’empreinte vous-même. Ce cours fixe l’étiquette exacte. Vous vérifiez s’il existe une image plus récente quand vous travaillez sur le projet. Une équipe ayant un outil qui met automatiquement les empreintes à jour peut fixer l’empreinte.
Aujourd’hui, python:3.14-slim et python:3.14.8-slim-trixie ont la même empreinte. La sortie de construction ci-dessus affichait sha256:f85c5697… pour les deux. L’étiquette est seulement un nom; l’empreinte représente le contenu.
Les lignes ENV et une image plus petite
Section intitulée « Les lignes ENV et une image plus petite »ENV définit une variable d’environnement dans l’image. La construction et chaque conteneur l’utilisent. Ajoutez ces lignes après FROM :
ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ PIP_NO_CACHE_DIR=1 \ PIP_DISABLE_PIP_VERSION_CHECK=1 \ PIP_ROOT_USER_ACTION=ignore| Variable | Son effet | Pourquoi |
|---|---|---|
PYTHONDONTWRITEBYTECODE=1 |
Python n’écrit pas de fichiers .pyc. |
Le conteneur n’en a pas besoin. Dans la prochaine leçon, l’application n’aura pas le droit d’écrire dans /app. |
PYTHONUNBUFFERED=1 |
Python écrit chaque ligne de journal immédiatement. | docker logs affiche une ligne au moment de l’événement, pas plus tard. |
PIP_NO_CACHE_DIR=1 |
pip ne conserve pas de copie de chaque téléchargement. | La copie resterait dans la couche, et personne ne l’utiliserait. |
PIP_DISABLE_PIP_VERSION_CHECK=1 |
pip ne cherche pas de version plus récente de pip. | La construction est plus rapide, sans message à ce sujet. |
PIP_ROOT_USER_ACTION=ignore |
pip n’avertit pas qu’il s’exécute comme root. | La construction s’est exécutée comme root et a affiché WARNING: Running pip as the 'root' user can result in broken permissions… (avertissement : exécuter pip comme root peut causer des problèmes de permissions). Dans une image, c’est normal. |
Le \ à la fin d’une ligne continue l’instruction sur la ligne suivante. Ensemble, l’étiquette fixée, les lignes ENV et .dockerignore changent l’image :
| Première image (leçon 1) | Maintenant | |
|---|---|---|
docker image ls : espace disque utilisé / taille du contenu |
363MB / 86.8MB | 309MB / 65.3MB |
Couche RUN pip install (docker history) |
117MB | 84.1MB |
Couche COPY ticket_api |
102kB | 49.2kB |
La couche pip est 33 Mo plus petite, car elle ne contient pas de cache pip. La couche du code fait la moitié de sa taille, car elle ne contient pas de __pycache__. La taille du contenu est celle des couches compressées qu’un envoi ou une récupération transfère sur le réseau. L’espace disque utilisé est leur taille décompressée sur votre ordinateur.
De petites images de base fiables
Section intitulée « De petites images de base fiables »L’image de base représente la majeure partie de votre image. Vous obtenez tous ses programmes et tous ses problèmes de sécurité. Amira a comparé trois variantes de Python 3.14.8 (linux/arm64, avec docker image ls --tree) :
| Image de base | Espace disque utilisé | Taille du contenu | Contient un compilateur C (gcc) et curl |
|---|---|---|---|
python:3.14.8-trixie |
1.62GB | 405MB | Oui |
python:3.14.8-slim-trixie |
204MB | 43.8MB | Non |
python:3.14.8-alpine |
85.9MB | 21.1MB | Non |
L’image complète contient des outils de construction pour les paquets qui doivent être compilés. Les paquets d’Amira n’en ont pas besoin. La variante slim est donc huit fois plus petite, sans rien manquer.
Alpine est encore plus petite, mais utilise une bibliothèque C différente, musl, au lieu de glibc. pip peut alors utiliser seulement des wheels (paquets prêts à installer) construits pour musl, avec musllinux dans leur nom de fichier. Amira a essayé pip install -r requirements-run.txt sur python:3.14.8-alpine. Les huit paquets contenant du code compilé, comme pydantic_core et uvloop, avaient un wheel musllinux, et l’installation a fonctionné. Un paquet sans ce type de wheel doit être compilé, et l’image Alpine n’a pas de compilateur. Vérifiez chaque paquet avant de choisir Alpine, puis vérifiez de nouveau quand vous en ajoutez un. Le cours utilise slim.
Choisissez une image de base fiable. python est une Docker Official Image (image officielle Docker) : Docker la révise, et elle reçoit des mises à jour de sécurité. Sa page sur Docker Hub, hub.docker.com/_/python, énumère toutes les étiquettes. Une image provenant d’un compte inconnu peut contenir n’importe quoi.
Exercice guidé : une construction rapide, petite et à version fixe
Section intitulée « Exercice guidé : une construction rapide, petite et à version fixe »-
Créez
.dockerignoredans le dossier du projet, comme dans Le contexte de construction et .dockerignore. -
Dans le
Dockerfile, remplacez la première ligne parFROM python:3.14.8-slim-trixie. -
Ajoutez les lignes
ENVaprèsFROM, comme dans Les lignes ENV et une image plus petite. Votre Dockerfile ressemble maintenant à ceci :Dockerfile FROM python:3.14.8-slim-trixieENV PYTHONDONTWRITEBYTECODE=1 \PYTHONUNBUFFERED=1 \PIP_NO_CACHE_DIR=1 \PIP_DISABLE_PIP_VERSION_CHECK=1 \PIP_ROOT_USER_ACTION=ignoreWORKDIR /appCOPY requirements-run.txt .RUN pip install -r requirements-run.txtCOPY pyproject.toml .COPY ticket_api ./ticket_apiEXPOSE 8000CMD ["fastapi", "run", "--host", "0.0.0.0", "--port", "8000"] -
Prédisez les étapes qui s’exécuteront, puis construisez l’image avec
docker build -t ticket-api:1.0.0 .. -
Vérifiez la ligne
transferring context(transfert du contexte). Elle indique quelques kilooctets. -
Exécutez
docker image ls ticket-api. L’image fait environ 309 Mo. -
Exécutez
docker run --rm ticket-api:1.0.0 ls -a /app. La liste contient seulementpyproject.toml,requirements-run.txtetticket_api. -
Démarrez le conteneur et appelez
/health, comme dans L’essentiel du Dockerfile : exécuter l’image. La réponse est{"status":"ok"}.
Afficher la sortie de construction attendue à l’étape 4
Toutes les étapes s’exécutent. Les lignes ENV viennent juste après FROM. Chaque étape qui les suit a donc une nouvelle instruction avant elle. Voici les lignes des étapes, avec un outil de construction dont le cache est vide :
=> [1/6] FROM docker.io/library/python:3.14.8-slim-trixie@sha256:f85c569 5.5s ... => [2/6] WORKDIR /app 0.2s => [3/6] COPY requirements-run.txt . 0.0s => [4/6] RUN pip install -r requirements-run.txt 19.7s => [5/6] COPY pyproject.toml . 0.1s => [6/6] COPY ticket_api ./ticket_api 0.1sLes lignes ENV n’ont pas d’étape distincte : comme EXPOSE, elles écrivent seulement des paramètres. Vos durées peuvent être différentes. Si cet ordinateur a déjà construit les mêmes étapes, certaines lignes peuvent indiquer CACHED (en cache). Étape 6 :
IMAGE ID DISK USAGE CONTENT SIZE EXTRAticket-api:1.0.0 ee0aa1f19820 309MB 65.3MBÉtape 7 :
...pyproject.tomlrequirements-run.txtticket_apiÀ vous de jouer : prédire un changement dans pyproject.toml
Section intitulée « À vous de jouer : prédire un changement dans pyproject.toml »Ajoutez une ligne de commentaire à la fin de pyproject.toml, par exemple # Built with Docker. Avant la construction, notez les étapes qui indiqueront CACHED et celles qui s’exécuteront. Ensuite, construisez l’image, vérifiez le résultat et supprimez le commentaire.
Afficher la réponse
Les étapes 2 à 4 indiquent CACHED, donc pip install ne s’exécute pas. L’étape 5, COPY pyproject.toml ., s’exécute parce que le fichier a changé. L’étape 6 s’exécute parce qu’elle vient après l’étape 5 :
[+] Building 0.3s (11/11) FINISHED docker:desktop-linux => [1/6] FROM docker.io/library/python:3.14.8-slim-trixie@sha256:f85c569 0.0s => CACHED [2/6] WORKDIR /app 0.0s => CACHED [3/6] COPY requirements-run.txt . 0.0s => CACHED [4/6] RUN pip install -r requirements-run.txt 0.0s => [5/6] COPY pyproject.toml . 0.0s => [6/6] COPY ticket_api ./ticket_api 0.0sticket_api n’a pas changé, mais sa couche repose sur la nouvelle couche de l’étape 5. Il faut donc la créer à nouveau. Après la suppression du commentaire, la construction suivante indique CACHED partout.
Erreur courante
COPY échoue avec le message « not found », mais le fichier est là
Symptôme : après un changement dans .dockerignore, la construction s’arrête :
#9 [5/6] COPY pyproject.toml .#9 ERROR: failed to calculate checksum of ref 65tu4hq3l2veiuoltpznypryw::4xw03kvqm5pe2q3u3gfngbhsy: "/pyproject.toml": not found...ERROR: failed to build: failed to solve: failed to compute cache key: failed to calculate checksum of ref 65tu4hq3l2veiuoltpznypryw::4xw03kvqm5pe2q3u3gfngbhsy: "/pyproject.toml": not foundls montre que pyproject.toml se trouve dans le dossier du projet.
Cause : le fichier est sur votre ordinateur, mais pas dans le contexte de construction. Ici, la ligne !pyproject.toml manquait dans la liste d’autorisation. Ainsi, * a ignoré le fichier, et COPY ne peut pas le voir. Le message indique « not found » (introuvable) parce que, pour l’outil de construction, le fichier n’existe pas.
Solution : ajoutez le fichier à la liste d’autorisation avec une ligne !, puis relancez la construction. Quand vous ajoutez un fichier nécessaire à l’image, ajoutez-le à COPY et à .dockerignore.
Pour un vrai service d’IA : cette erreur montre que la liste d’autorisation fait son travail. Si elle omet un fichier de modèle nécessaire à l’image, la construction échoue avec une erreur claire. C’est mieux qu’un secret qui entre dans l’image sans avertissement. Préférez une erreur de construction claire à une fuite silencieuse.
Vérifiez votre compréhension
Pourquoi le Dockerfile d'Amira copie-t-il requirements-run.txt et exécute-t-il pip install avant de copier ticket_api?
Afficher la réponse
Le code change souvent et la liste des paquets change rarement. Docker réutilise les étapes en cache seulement jusqu’à la première étape dont l’entrée a changé. Cette étape et toutes les suivantes s’exécutent à nouveau. Avec les paquets en premier, un changement de code exécute seulement COPY ticket_api (0,4 s ici). Le résultat de pip install vient alors du cache. Avec le code en premier, chaque changement de code réinstalle les 50 paquets (environ 16 s ici).
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Vérifiez votre compréhension
Le fichier .dockerignore de Sam liste les éléments à exclure : .venv, .git et .env. La semaine prochaine, l'équipe ajoute un fichier secrets/db_password.txt. Que se passe-t-il avec le fichier de Sam et avec la liste d'autorisation?
Afficher la réponse
Dans la liste d’exclusion de Sam, secrets/db_password.txt ne figure pas. Il entre donc dans le contexte de construction. Si le Dockerfile contient COPY . ., le mot de passe entre dans l’image. Avec la liste d’autorisation, * ignore tous les fichiers, y compris les nouveaux. Seuls requirements-run.txt, pyproject.toml et ticket_api/ peuvent atteindre la construction. Le nouveau fichier reste donc exclu sans aucun changement à .dockerignore.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Vérifiez votre compréhension
Quelle différence y a-t-il entre fixer python:3.14.8-slim-trixie et fixer son empreinte? Donnez un avantage de chaque option.
Afficher la réponse
L’étiquette exacte désigne une version de Python, une variante et une version de Debian. Mais ses responsables peuvent publier une nouvelle construction sous la même étiquette, par exemple avec un correctif de sécurité. Avantage : vous obtenez ces correctifs à la prochaine construction. L’empreinte est une somme de contrôle du contenu exact, donc l’image ne peut jamais changer. Avantage : chaque construction utilise les mêmes octets. En contrepartie, vous devez mettre à jour l’empreinte vous-même pour obtenir les correctifs.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Récapitulatif
- Le cache des couches réutilise chaque étape jusqu’à la première étape dont l’entrée a changé. Cette étape et toutes les suivantes s’exécutent à nouveau.
- Placez d’abord ce qui change rarement : l’image de base, la liste des paquets,
pip install, puis le code. Un changement de code permet alors une reconstruction en moins d’une seconde. - Une liste d’autorisation dans
.dockerignoreenvoie seulement trois éléments à la construction..env,.venvet.gitne peuvent pas atteindre l’image. - Fixez l’image de base à une étiquette exacte (
python:3.14.8-slim-trixie) et les paquets à des versions exactes. Une empreinte offre la fixation la plus stricte. - Une Docker Official Image de variante slim est petite et fiable. Les lignes ENV et
.dockerignoreont réduit l’image à 309 Mo au lieu de 363 Mo.
Ensuite, vous ferez fonctionner l’application avec un compte utilisateur ordinaire. Vous prouverez aussi qu’un secret dans une couche de construction reste dans l’image après sa suppression.
Leçon suivante : Sécurité à l'exécution