0043 — Publication des images de déploiement sur GHCR
Contexte
Section intitulée « Contexte »La Phase 4 du plan cloud-native (#308)
dote les unités déployables d’une image de déploiement sur le patron de
apps/sillage/Dockerfile. Cette première étape couvre les unités dont la
config est entièrement runtime ou publique — atlas-dashboard,
crf-dashboard et le service Hono — qui buildent et se déploient sans
secret figé. Les apps qui lisent des secrets via $env/static/private
(amarre, ecrin, find-an-expert, sillage) sont différées : ce
mécanisme fige les valeurs au build, donc leur image n’est pas déployable
telle quelle ; elles rejoindront la publication une fois migrées vers
$env/dynamic/private (lecture runtime) —
#324. Le
contrat d’interface avec le cluster (ADR 0033)
fixe déjà que atlas livre des images taguées au cluster, poussées sur un
registry que les manifestes référencent par tag exact (« pas de latest en
production »). Il fixe la forme des images et leur tag, mais ne disait
rien de où et quand elles sont publiées ni de comment la CI les fabrique.
Aujourd’hui, rien ne publie ces images : la CI les ignore. Le workflow
release.yml publie des paquets npm, pas des conteneurs ; aucun job ne
construit les Dockerfile. Conséquence déjà constatée : le patron sillage
portait deux bugs de fabrication latents (le prepare racine échouant sans
git, une dépendance runtime classée en devDependency) qu’aucune CI n’a
jamais attrapés, faute de construire l’image. Une image qui n’est jamais
construite en CI dérive en silence.
Le contrat 0033 mentionne « un registry interne » côté cluster, « déjà en
prod ». Mais ce registry est interne au cluster : il n’est pas une cible
naturelle pour la CI d’atlas (réseau, credentials, couplage inverse au
déploiement). Il faut une cible de publication propre au dépôt applicatif,
que le cluster peut ensuite consommer ou mirrorer.
Décision
Section intitulée « Décision »La CI d’
atlasconstruit et publie les images de déploiement sur GitHub Container Registry (GHCR), sousghcr.io/univ-lehavre/<nom-d'image>. Chaque image est poussée depuismain, taguée par le SHA de commit court (immuable) et par la version sémver dupackage.jsonde l’unité — jamaislatestcomme référence de déploiement. Sur les pull requests, la CI construit et teste les images (smoke healthcheck) sans publier.
GHCR comme registry de publication de l’application
Section intitulée « GHCR comme registry de publication de l’application »GHCR est le registry du dépôt : intégré à GitHub, authentifié par le
GITHUB_TOKEN du workflow (permission packages: write), sans secret à gérer ni
infrastructure à provisionner. Il devient la source de vérité des images
publiées par atlas. Cela étend le contrat 0033 sans le contredire :
0033 fixe que les manifestes du cluster référencent des images taguées sur un
registry ; cet ADR précise que le registry d’origine est GHCR. Le registry
interne du cluster reste libre de mirrorer depuis GHCR (décision du dépôt
cluster, hors de cet ADR) ; ce qui change, c’est qu’atlas a désormais un
point de publication explicite et automatisé, au lieu d’aucun.
Tags : SHA immuable + version lisible, jamais latest en déploiement
Section intitulée « Tags : SHA immuable + version lisible, jamais latest en déploiement »Chaque image reçoit deux tags :
sha-<court>— le SHA de commit court. Immuable : un tag SHA pointe à jamais vers le même contenu. C’est ce qu’un manifeste de déploiement référence (traçabilité exacte commit → image, conforme au « tag exact » de 0033).<version>— la version sémver dupackage.jsonde l’unité (p. ex.3.1.0). Lisible, pour les humains et les montées de version ; peut être ré-publiée si la version est bumpée, donc moins forte garantie que le SHA.
On n’utilise pas latest comme référence de déploiement (règle 0033). Un
latest indicatif pointant sur le dernier build de main peut exister pour la
DX (essai local rapide), mais aucun manifeste ne doit le référencer.
PR : construire et tester, ne pas publier
Section intitulée « PR : construire et tester, ne pas publier »Sur pull request, la CI construit chaque image touchée et lance un smoke
test (démarrage du conteneur + HEALTHCHECK vert), mais ne pousse rien.
La publication n’a lieu que depuis main (intégration faite, revue passée). Cela
ferme la dérive silencieuse — toute régression de fabrication casse la PR — sans
publier d’images non revues.
CI adaptative : ne construire que ce qui change
Section intitulée « CI adaptative : ne construire que ce qui change »Le job suit la logique de l’ADR 0034 :
une image n’est (re)construite que si son Dockerfile, son code, ou une de ses
dépendances workspace a changé — ou si un fichier transverse (lockfile,
.nvmrc, le workflow lui-même) bouge. On évite de reconstruire toutes les
images à chaque PR documentaire.
Accepted (2026-06-04).
Conséquences
Section intitulée « Conséquences »Bénéfices.
- Les images existent vraiment et sont vérifiées en continu : plus de
Dockerfilequi pourrit sans que personne ne le sache (le cassillagene se reproduit pas). atlasa enfin un point de publication explicite des images, automatisé, sans infrastructure à provisionner ni secret à gérer (leGITHUB_TOKENsuffit).- La traçabilité commit → image est exacte (tag SHA immuable), ce que le contrat 0033 demande aux manifestes.
- Le cluster peut consommer ou mirrorer depuis une source stable et publique au dépôt, au lieu de dépendre d’un build manuel.
Prix à payer.
- GHCR devient une dépendance de publication : un dépôt indisponible bloque la livraison d’images (mais pas le build/test, qui restent en CI).
- Les images publiques sur GHCR exposent la surface applicative (couches,
dépendances) à qui peut lire le registry ; aucun secret n’y transite (les
PRIVATE_*sont injectées au runtime, cf. 0033), mais la visibilité du paquet doit être gérée côté GitHub (org). - Deux registres possibles (GHCR + éventuel mirror cluster) : une cohérence à
maintenir, traitée côté
cluster.
Garde-fous.
- Jamais de secret dans une image : les
PRIVATE_*n’entrent pas dans lebuilder(elles resteraient dans l’historique des couches poussées) — règle déjà posée par l’ADR 0033. - Pas de
latestréférencé en déploiement : les manifestes citent un tag SHA ;latestreste au plus un confort de DX local. - Publication depuis
mainuniquement : les PR construisent et testent mais ne poussent pas. - Le registry interne du cluster et son éventuel mirror relèvent du dépôt
clusteret de son contrat d’interface ; cet ADR ne décide que de la publication côté application.