Aller au contenu principal
Nicolas Cousin Tech SolutionsNicolas Cousin Tech Solutions
Module 2 sur 6

Mémo de décision : image pré-construite vs à la volée

Le scénario

Votre setup du module 01 fonctionne : app + db, hostname db joignable, tout est documenté. Mais un nouveau contributeur vient de cloner le repo et se plaint : ouvrir le Dev Container prend plusieurs minutes avant qu'il puisse taper la moindre ligne de code, parce que Docker doit reconstruire l'image app depuis le Dockerfile à chaque fois que le cache local est invalidé (changement de branche, machine neuve, CI qui tourne dans un environnement froid).

Votre lead technique vous pose la question directement : est-ce qu'on publie des images devcontainer pré-construites sur un registre, ou est-ce qu'on continue à construire à la volée sur chaque poste ?

Il n'y a pas de réponse universelle — ça dépend de la taille de l'équipe, de la fréquence des changements de Dockerfile, et de ce que votre CI peut déjà faire. Votre travail : produire un mémo de décision, pas réciter une règle.

Consigne : écrivez votre mémo avant de continuer

Avant de lire la suite de ce module, prenez votre setup du module 01 (ou un devcontainer.json réel que vous avez sous la main) et faites ceci, dans l'ordre :

1. Mesurez votre temps de build réel.

docker builder prune -f   # videz le cache pour un build à froid honnête
time docker build -f .devcontainer/Dockerfile -t bench-app .

Notez le temps réel (real dans la sortie de time). C'est votre borne haute — un build à froid complet, comme le vivrait un nouveau contributeur ou un runner CI éphémère sans cache.

2. Estimez ce qu'un docker pull équivalent coûterait.

Vous n'avez pas forcément d'image déjà publiée pour mesurer un vrai pull à froid — c'est normal. Estimez à partir de la taille de l'image :

docker images bench-app --format "{{.Size}}"

Une image de quelques centaines de Mo à 1-2 Go se télécharge typiquement en quelques dizaines de secondes sur une connexion d'équipe correcte — très inférieur à un build multi-minutes qui compile des dépendances. Notez votre propre estimation, avec la taille mesurée et une hypothèse de bande passante raisonnable.

3. Écrivez un tableau de compromis. Trois colonnes minimum : temps (build à froid vs pull), coût de stockage/registre (une image de X Go, combien de versions conservées, sur quel registre — GHCR est gratuit pour repos publics, payant au-delà d'un quota pour privés), risque de péremption (staleness — si l'image n'est reconstruite qu'une fois par semaine, un contributeur peut travailler sur une base légèrement désynchronisée du Dockerfile actuel).

4. Tranchez, par écrit, en une ou deux phrases, avec la justification qui vous a fait pencher d'un côté — pas juste "on pré-construit" mais "on pré-construit parce que [raison spécifique à vos chiffres]".

Ne continuez pas tant que vous n'avez pas ces quatre éléments écrits, même de façon informelle.


Grille de comparaison, pour vous auto-évaluer

Voici ce que la documentation officielle de containers.dev, le guide dédié au prebuild, met en avant — comparez-le à votre propre mémo, ne le recopiez pas rétroactivement.

Ce que le prebuild apporte, selon la doc officielle

  • Rapidité : « tirer une configuration de dev container déjà construite plutôt que devoir la construire à neuf sur chaque nouvelle machine ».
  • Simplicité : le devcontainer.json du contributeur final peut se réduire à un simple champ image pointant vers l'image publiée — plus besoin que chaque poste rejoue tout le Dockerfile.
  • Sécurité et stabilité : figer une version précise des outils dans l'image publiée « améliore la sécurité de la chaîne d'approvisionnement et évite les ruptures » — un contributeur qui build à la volée peut, sans le vouloir, récupérer une version plus récente d'une dépendance système au moment du build, ce qu'une image figée empêche.

Notez ce que la doc officielle ne couvre pas explicitement : le coût de stockage sur le registre, et le risque de staleness (image en retard sur le Dockerfile source) ne sont pas analysés dans le guide — c'est un point mort de la documentation, précisément l'endroit où le jugement de l'équipe doit combler le vide. Si votre mémo a identifié ce manque tout seul, c'est bon signe.

Comment le prebuild est mis en place, techniquement

Le flux documenté par containers.dev :

  1. Installer la CLI officielle : npm install -g @devcontainers/cli
  2. Construire et publier l'image : devcontainer build --workspace-folder . --push true --image-name <registre>/<namespace>/<nom>
  3. Automatiser ce build via un pipeline — GitHub Actions ou Azure DevOps sont les deux exemples officiellement documentés — pour que l'image se reconstruise à chaque changement pertinent (typiquement : un push qui touche le Dockerfile ou le docker-compose.yml), plutôt qu'un contributeur qui la reconstruit manuellement.

Un devcontainer.json de contributeur final, une fois l'image publiée, peut alors devenir :

{
  "name": "App + PostgreSQL",
  "image": "ghcr.io/votre-org/votre-repo-app:latest",
  "workspaceFolder": "/workspace"
}

(Notez que ceci ne remplace pas docker-compose.yml pour le service db — dans un setup multi-services, seule l'image du service applicatif est généralement pré-construite ; une base de données comme postgres:16 est déjà une image officielle publiée, donc déjà "pré-construite" par nature.)

Checklist de décision

Comparez votre mémo à ces points, sans chercher une correspondance exacte — il n'y a pas de "bonne" réponse unique, seulement un raisonnement traçable :

  • Avez-vous mesuré (pas estimé à vue de nez) votre temps de build à froid réel ?
  • Votre tableau distingue-t-il clairement le coût ponctuel (temps de build) du coût récurrent (stockage registre, maintenance du pipeline de prebuild) ?
  • Avez-vous identifié QUI paie le coût de staleness si vous choisissez le prebuild — l'équipe qui doit se souvenir de relancer un build manuel, ou un pipeline automatique déclenché sur push ?
  • Votre décision cite-t-elle un chiffre ou un seuil (« si le build dépasse X minutes », « si l'équipe dépasse X contributeurs ») plutôt qu'une préférence générale ?
  • Avez-vous noté ce qui casse si le pipeline de prebuild lui-même tombe en panne — un devcontainer.json réduit à image sans fallback build local rend l'équipe dépendante de la disponibilité du registre.

Si votre mémo touche ces cinq points, vous avez produit une vraie décision d'ingénierie, pas une opinion.

Ce qui vous attend au module suivant

Le module suivant change de sujet : on quitte l'architecture du conteneur pour s'assurer que vos hooks pre-commit locaux sont réellement appliqués en CI, pas seulement sur votre poste.

Vérifiez votre compréhension

D'après le guide officiel containers.dev sur le prebuild, quel bénéfice N'EST PAS explicitement mis en avant ?

Un pipeline de prebuild qui pousse une nouvelle image sur chaque merge vers main résout automatiquement quel risque, mais en introduit lequel ?

Si l'équipe choisit le prebuild MAIS sans pipeline CI automatique (un mainteneur relance le build à la main de temps en temps), qui « paie » le coût si l'image devient obsolète ?

Envie d'être prévenu des prochains modules ?

L'Académie reste gratuite et en accès libre, sans inscription. Si vous voulez juste être averti par email à la sortie d'un nouveau module, c'est ici — aucune obligation, désinscription en un clic.