Bloc 97 — 🐛 CI : « Verify Docker Compose health » rouge sur main (mauvaise image) - #122
Merged
Merged
Conversation
…nstruire Diagnostic (run 34835198084, commit 065ed7a sur main). L'erreur exacte, dans les logs de l'étape : Container ml-helper-app-1 Error response from daemon: No such image: ghcr.io/magicgg91/ml-helper:dev Le conteneur n'a donc jamais démarré : ce n'est ni un healthcheck qui échoue, ni un timeout. L'étape a duré moins d'une seconde (10:59:11 → 10:59:11), loin des 180 s de `--wait-timeout`, et « Show Docker Compose logs on failure » n'a rien affiché — il n'y avait aucun conteneur. Cause : le job construit et charge `:latest` sur main, `:dev` ailleurs, mais l'étape Compose ne passait pas `ML_HELPER_IMAGE`. Compose retombait donc sur son propre défaut, `:dev` (docker-compose.yml), avec `--pull never`. Sur dev les deux chaînes coïncidaient par hasard ; sur main elles divergent, et l'image demandée n'avait jamais existé sur le runner. Jamais vu avant parce que ce chemin n'avait jamais été emprunté : l'étape Compose et la variable ML_HELPER_IMAGE sont arrivées ensemble le 2026-09-02 (ccc1481), et le dernier push sur main avant celui-ci datait du 2026-08-31. Ce run est la première exécution de cette étape sur main. Aucun secret ni variable d'environnement ne manque : l'étape fait `touch .env`, toutes les variables du compose ont un défaut `:-`, le login ghcr a réussi, et l'échec précède de toute façon toute lecture d'environnement. Correctif : nommer l'image une seule fois, au niveau du job, sous le nom que Compose lit lui-même (ML_HELPER_IMAGE). Les quatre étapes (build, vérification de démarrage, Compose, push) s'y réfèrent, donc les deux fichiers ne peuvent plus diverger. Le défaut `:dev` de docker-compose.yml reste inchangé — il est documenté dans README.md. La description du statut GitHub publié en cas d'échec accusait la santé du conteneur pour un conteneur qui n'avait jamais démarré ; elle couvre maintenant les deux cas. Reproduction locale, à l'identique : avec seulement `:latest` en local (ce que fait le job sur main), `docker compose up -d --pull never` sort le même « No such image: ghcr.io/magicgg91/ml-helper:dev » ; en passant ML_HELPER_IMAGE, l'erreur disparaît. L'image réelle n'a pas pu être construite ici (la politique réseau de l'environnement bloque le pull des images de base Docker Hub), donc le passage jusqu'à « healthy » reste à confirmer par le prochain push sur main. Test : src/foundation.test.ts épingle le lien entre les deux fichiers — Compose lit bien ${ML_HELPER_IMAGE:-}, le workflow le définit, et le tag n'est écrit qu'une fois hors commentaires. Contre-vérifié : retirer la variable rougit 2 tests, remettre un tag en dur dans une étape en rougit 1. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJgsDSfsCbbn8cochFGwe2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Cause, confirmée par les logs
L'erreur exacte, dans les logs de l'étape (run 34835198084) :
Des trois pistes du brief, c'est la première : le conteneur n'a jamais démarré. Ni healthcheck en échec, ni timeout. Trois faits le confirment :
10:59:11→10:59:11), loin des 180 s de--wait-timeout;docker compose down --volumesn'a retiré qu'un réseau, aucun conteneur.Le mécanisme. Le job construit et charge
ghcr.io/magicgg91/ml-helper:latestsurmain,:devailleurs. Mais l'étape Compose ne passait pasML_HELPER_IMAGE: Compose retombait donc sur son propre défaut,:dev(docker-compose.yml:3), avec--pull neverqui interdit d'aller le chercher. Surdevles deux chaînes coïncidaient — par coïncidence, pas par construction. Surmainelles divergent, et l'image demandée n'avait jamais existé sur le runner.Pourquoi jamais vu avant. Ton intuition était la bonne, et l'historique la confirme : l'étape Compose et la variable
ML_HELPER_IMAGEsont arrivées ensemble le 2026-09-02 (ccc1481, PR #86), et le dernier push surmainavant celui-ci datait du 2026-08-31. Ce run est la toute première exécution de cette étape surmain.Ce n'est pas un secret ou une variable manquante. L'étape fait
touch .env, toutes les variables du compose ont un défaut:-, ledocker/login-actiona réussi, et l'échec précède de toute façon toute lecture d'environnement.Reproduction locale — à l'identique
Avec uniquement
:latestprésent en local (ce que fait le job surmain), la commande exacte de l'étape :Même message, au caractère près. En passant
ML_HELPER_IMAGE, l'erreur disparaît (0 occurrence).Limite honnête : la politique réseau de cet environnement bloque le pull des images de base Docker Hub (403 sur
production.cloudfront.docker.com), je n'ai donc pas pu construire l'image réelle et aller jusqu'àhealthy— j'ai reproduit la résolution d'image, qui est exactement là où ça cassait. Le trajet complet jusqu'àhealthysera confirmé par le prochain push surmain.Correctif
Nommer l'image une seule fois, au niveau du job, sous le nom que Compose lit lui-même :
Les quatre étapes (build, vérification de démarrage, Compose, push) s'y réfèrent désormais. Compose reçoit l'image que le job vient de construire, sur les deux branches, et les deux fichiers ne peuvent plus diverger. Le défaut
:devdedocker-compose.ymlreste inchangé : il est documenté dansREADME.md:28comme le canal roulant, et le changer modifierait le comportement de ton déploiement.En prime, une ligne : la description du statut GitHub publié en cas d'échec accusait la santé d'un conteneur qui n'avait jamais démarré. C'est ce qui a rendu ce diagnostic nécessaire — elle couvre maintenant les deux cas.
Test
src/foundation.test.ts(qui teste déjà Compose/Dockerfile/healthcheck en texte) épingle le lien entre les deux fichiers : Compose lit bien${ML_HELPER_IMAGE:-}, le workflow le définit, et le tag n'est écrit qu'une seule fois hors commentaires.Contre-vérifié dans les deux sens : retirer la variable (l'état d'avant) rougit 2 tests ; remettre un tag en dur dans une étape en rougit 1.
Validation
pnpm lint: proprepnpm test: 1275 tests verts (+2)jobs.image.envbien luci.ymlétait déjà hors format Prettier avant ce changement (vérifié sur la version HEAD) — je ne l'ai pas reformaté, la dérive n'est pas de mon faitLe job
imagene tourne que surpush(if: github.event_name == 'push'), donc la CI de cette PR n'exercera pas le correctif — seul le jobtests'exécutera. Il sera exercé au push surdevaprès merge (tag:dev, le chemin qui marchait déjà), et réellement validé au prochain mergedev→main.Et
mainreste rouge jusqu'à ce prochain merge : le jobimagene se relancera surmainqu'au prochain push.🤖 Generated with Claude Code
https://claude.ai/code/session_01HJgsDSfsCbbn8cochFGwe2
Generated by Claude Code