Conversation
Builds re-did every step on each run: the full apt/pip setup and a complete `poetry install`, both of them twice because the image is built for amd64 and arm64. - Import and export the GitHub Actions cache in the Docker build job, and cache the Poetry virtualenv in the lint job. - Install dependencies before copying the source, so the install layer is rebuilt only when the lockfile changes. - Mount a per-architecture BuildKit cache for Poetry's downloads. - Drop gcc: every dependency ships prebuilt wheels for both target architectures, so the apt layer is no longer needed (479MB -> 313MB). A multi-arch build takes 203s with an empty cache and 16s once the cache is imported. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The floating `python:3.13-slim` tag moved silently: nothing recorded when the base image changed, and the same commit could build a different image. Pinning makes builds reproducible and turns each base update into a reviewable pull request. The tag names the exact version and Debian suite alongside the digest so the two agree: a Python patch bump reads as 3.13.15 -> 3.13.16 in the diff, and a move to a new Debian suite has to rewrite `-trixie` rather than arriving as an opaque digest change. Dependabot only compares tags sharing the same suffix, so `-slim-trixie` keeps tracking its own variant; a digest with no tag would be tracked against `python:latest`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
🇬🇧 English
🎯 Summary
CI rebuilt the Docker image from scratch on every run. This branch adds a layer cache, reorders the Dockerfile so dependencies survive source changes, drops a compiler that turned out to be unused, and pins the base image by digest.
🤔 Motivation
The
docker-build-checkjob had no cache at all, so each run redid the full apt/pip setup and a completepoetry install— twice, since the image is built forlinux/amd64andlinux/arm64, with one half under QEMU emulation. A cache alone would have under-delivered:COPY ./ /appsat abovepoetry install, so any source change invalidated the dependency layer.Separately,
FROM python:3.13-slimwas a floating tag. Base image updates arrived silently — no pull request, no record, no rollback point — and the same commit could build a different image.📦 What's included
lintjob (setup-pythonnow runs after Poetry is installed, which it needs).poetry installlayer is rebuilt only when the lockfile changes.gcc: every dependency ships prebuilt wheels for both target architectures, which removes the apt layer entirely — 479 MB → 313 MB, and no compiler in the production image.python:3.13.15-slim-trixie@sha256:9d2e5553…, so a Python patch bump reads as a version change in the diff and a Debian suite migration cannot arrive as an opaque digest change.alembic 1.20.0verified,hadolintclean with no ignores,actionlintclean.🧭 Notes
master, so the scope has to be populated by amasterbuild before the gain shows.renovate.jsonanddependabot.ymlboth watch Docker. With a digest now inFROM, that line is the most likely place for the two bots to collide.dependabot.ymlcarriescooldown: default-days: 7, which delays base-image security patches by a week — the path we rely on now that the image no longer runsapt-get upgrade.deploy.yml,cache-toon a tag run writes to a scope nothing can read back; only itscache-fromdoes real work. Left as-is, out of scope here.USERis deliberately not in this branch — it needs achownon the server's bind-mountedlogs/anddata/, and is handled separately.🇫🇷 Français
🎯 Résumé
La CI reconstruisait l'image Docker intégralement à chaque exécution. Cette branche ajoute un cache de couches, réordonne le Dockerfile pour que les dépendances survivent aux modifications de source, retire un compilateur finalement inutile, et épingle l'image de base par digest.
🤔 Motivation
Le job
docker-build-checkn'avait aucun cache : chaque exécution refaisait toute l'installation apt/pip et unpoetry installcomplet — deux fois, puisque l'image est construite pourlinux/amd64etlinux/arm64, dont une moitié en émulation QEMU. Un cache seul n'aurait pas suffi :COPY ./ /appprécédaitpoetry install, donc toute modification de source invalidait la couche de dépendances.Par ailleurs,
FROM python:3.13-slimétait un tag flottant. Les mises à jour de l'image de base arrivaient silencieusement — sans pull request, sans trace, sans point de retour — et un même commit pouvait produire une image différente.📦 Contenu
lint(setup-pythons'exécute désormais après l'installation de Poetry, dont il a besoin).poetry installne soit reconstruite qu'au changement du lockfile.gcc: toutes les dépendances fournissent des wheels précompilées pour les deux architectures cibles, ce qui supprime la couche apt — 479 Mo → 313 Mo, et plus de compilateur dans l'image de production.python:3.13.15-slim-trixie@sha256:9d2e5553…: une montée de version corrective de Python se lit comme un changement de version dans le diff, et un changement de suite Debian ne peut plus arriver sous forme de digest opaque.alembic 1.20.0vérifiés,hadolintpropre sans aucune suppression,actionlintpropre.🧭 À noter
master, il faut donc qu'un build surmasterait rempli le scope avant que le gain apparaisse.renovate.jsonetdependabot.ymlsurveillent tous deux Docker. Avec un digest désormais dansFROM, cette ligne est l'endroit le plus probable d'une collision entre les deux bots.dependabot.ymlportecooldown: default-days: 7, ce qui retarde d'une semaine les correctifs de sécurité de l'image de base — le chemin sur lequel on s'appuie maintenant que l'image ne fait plusapt-get upgrade.deploy.yml, lecache-tod'une exécution sur tag écrit dans un scope que rien ne peut relire ; seul soncache-fromsert réellement. Laissé tel quel, hors périmètre.USERnon-root n'est volontairement pas dans cette branche : il impose unchownsur leslogs/etdata/montés côté serveur, et est traité séparément.📋 Checklist
masterbuild has populated the cache, confirm a later run shows a cache hit / 🇫🇷 Une fois le cache rempli par un build surmaster, vérifier qu'une exécution ultérieure montre un cache hit