L’image Docker
Une construction en plusieurs étapes, d’un seul Dockerfile : les dépendances mises en cache, le build autonome de Next, un migrateur à part et une image de service qui ne contient que ce qui s’exécute — sans un seul secret. Ce que chaque étape fait, pourquoi elle est là, et les deux corrections de cette relecture.
Précédemment. La qualité se vérifie sur la machine du développeur : pnpm check à chaque commit, les tests de bout en bout avant un déploiement. Reste à mettre le site en ligne.
Cette partie suit le site de la machine du développeur jusqu’au serveur : l’image qui le contient (ce chapitre), sa mise en production (chapitre 2), et la sandbox, une copie complète et autonome pour l’essayer sans rien risquer (chapitre 3).
Une image, des étapes 🐳#
Une image Docker est un système de fichiers figé : un Linux minimal, Node, l’application compilée, ce qu’il faut pour la lancer. Le serveur la construit à partir du dépôt, puis en démarre un conteneur. Le Dockerfile en est la recette, exécutée ligne à ligne ; chaque ligne produit une couche, que Docker garde en cache tant que ce dont elle dépend n’a pas changé.
Le Dockerfile du projet est multi-étapes : plusieurs FROM, chacun une image intermédiaire nommée, qui peut recopier des fichiers d’une étape précédente. Deux images en sortent :
Étape | Rôle | Sort de la construction ? |
|---|---|---|
base | Debian slim, Node 22, openssl, pnpm par Corepack. | Non : le socle des autres. |
deps | Les dépendances, installées depuis le fichier de verrouillage. | Non. |
builder | Le client Prisma généré, le build Next, sharp mis à plat. | Non : seuls ses résultats sont recopiés. |
migrator | Le schéma, les migrations, la CLI Prisma. | Oui : lancé avant de démarrer une nouvelle version, puis arrêté. |
runner | Le serveur Next autonome, ffmpeg, libheif. Rien d’autre. | Oui : le service qui répond aux visiteurs. |
Showing entries1to5entries
Séparer construction et service, c’est ne pas livrer les outils de construction : le compilateur TypeScript, ESLint, les sources, les dépendances de développement restent dans builder, qui n’est jamais démarré. L’image de service est plus petite, et ce qu’elle ne contient pas ne peut pas servir à un attaquant.
Dockerfile
Clique une étape pour mettre en évidence la zone correspondante dans le fichier complet.
// ⚠ Fichier introuvable : Dockerfile// Il a été déplacé ou supprimé depuis la rédaction de ce chapitre.Ordonner les couches du plus stable au plus changeant. Le système et les outils, puis les dépendances, puis le code. Une construction ne refait alors que ce qui a changé, et la suite : une ligne de code modifiée ne refait que les dernières couches.
Ce que Docker ne reçoit pas#
Avant de construire, Docker envoie au moteur le contexte : le dossier du dépôt, filtré par .dockerignore. Tout ce qui entre dans le contexte peut finir dans une couche, et une couche garde ce qu’on y a copié même si une étape suivante le supprime.
// ⚠ Fichier introuvable : .dockerignore// Il a été déplacé ou supprimé depuis la rédaction de ce chapitre.Aucun .env n’entre dans l’image : les secrets sont donnés au conteneur, au démarrage, par le serveur (partie « Configuration », chapitre « Les variables d’environnement »). Une image peut être partagée, poussée sur un registre, inspectée couche par couche ; elle ne contient rien qu’on ne puisse montrer.
La relecture a ajouté la construction des tests de bout en bout (.next-e2e, qui pèse plusieurs centaines de mégaoctets), les tests et leurs résultats, et les scripts apply-*.sh qu’on dépose à la racine du dépôt pour appliquer une modification : ils ne servent ni au build ni au site.
Exclu | Pourquoi |
|---|---|
node_modules, .next, .next-e2e | Reconstruits dans l’image, pour Linux : ceux du Mac viseraient une autre plateforme, et alourdiraient le contexte. |
.env, .env.* | Des secrets : jamais dans une couche. |
.git, .github, .vscode | L’historique et l’outillage : rien à faire dans le site. |
e2e, test-results, playwright-report | Les tests et leurs traces : utiles sur la machine, pas en production. |
apply-*.sh, *.sql, *.png de la racine | Des scripts et des fichiers de passage, parfois des sauvegardes : ce qui traîne à la racine n’entre pas. |
Showing entries1to5entries
Récapitulatif#
Question | Réponse du projet |
|---|---|
Combien d’images sort la construction ? | Deux : migrator (les migrations) et runner (le site). |
Pourquoi Debian slim et pas Alpine ? | La bibliothèque C d’Alpine impose à Prisma un moteur différent, à surveiller à chaque version. |
Pourquoi les dépendances dans une étape à part ? | pnpm install, la ligne la plus longue, vient du cache tant que les dépendances ne changent pas. |
Comment une NEXT_PUBLIC_ entre-t-elle dans le site ? | Par un argument de build, avec une valeur par défaut ; la changer impose de reconstruire. |
Sous quel utilisateur tourne le site ? | nextjs, sans privilèges. |
Où sont les secrets ? | Nulle part dans l’image : donnés au conteneur au démarrage. |
Qu’a changé la relecture ? | pnpm figé au build du migrateur, ffmpeg et libheif remontés avant la copie (en cache), contexte allégé, défaut de la racine de stockage. |
Showing entries1to7entries
À suivre#
L’image est prête. La mettre en production, c’est un ordre précis : le code, la migration, puis le nouveau conteneur — et savoir lire ce qu’il dit en démarrant.
Chapitre suivant : mettre en production. Ce qui vit sur le serveur, l’ordre d’un déploiement, ce que fait le site au démarrage, et comment revenir en arrière.