server-up/tests/test_dockerfile.py
Ramon 14515143fc
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 4m51s
perf(build): image bouwt niet meer alles opnieuw bij elke uitgave
ARG SU_VERSION stond bovenaan met een LABEL erachter. Die waarde verandert
per release, dus alle lagen erna vervielen: apt-get, de Docker-CLI van 70 MB
en de front-end-bestanden. Versie en label staan nu onderaan, en de assets
vóór de broncode zodat ze niet bij elke commit opnieuw van het CDN komen.

Ook: een mislukte pull noemt nu de waarschijnlijke oorzaak (geen gepusht
image) in plaats van alleen naar toegangsrechten te wijzen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H9Vcwu7owJZ3nj5dCf4VFT
2026-08-07 16:05:46 +02:00

59 lines
2.7 KiB
Python

"""De volgorde van de lagen in de Dockerfile bepaalt hoe lang een build duurt.
Docker hergebruikt een laag alleen zolang niets ervóór is gewijzigd. Stond het
versienummer bovenaan, dan gooide élke uitgave alles daarna weg: apt-get, de
Docker-CLI van 70 MB, de front-end-bestanden. Een release duurde daardoor een
kwartier terwijl er drie regels Python waren veranderd.
"""
from pathlib import Path
WORTEL = Path(__file__).resolve().parent.parent
REGELS = (WORTEL / "Dockerfile").read_text(encoding="utf-8").splitlines()
def _regel_van(fragment: str) -> int:
"""Het regelnummer van de eerste regel die dit fragment bevat."""
for i, r in enumerate(REGELS):
if fragment in r and not r.lstrip().startswith("#"):
return i
raise AssertionError(f"niet gevonden in de Dockerfile: {fragment}")
def test_de_broncode_komt_na_alles_wat_zelden_verandert():
"""De code wijzigt bij elke commit; wat daarvoor staat blijft in de cache."""
code = _regel_van("COPY server-up/ ./")
for eerder in ("apt-get update",
"download.docker.com",
"COPY --from=build /inst",
"static/fonts",
"static/vendor",
"mkdir -p /data/stacks"):
assert _regel_van(eerder) < code, \
f"'{eerder}' hoort vóór de broncode te staan, anders vervalt zijn cache"
def test_het_versienummer_staat_helemaal_onderaan():
"""SU_VERSION verandert per uitgave. Alles wat erná komt wordt opnieuw
gebouwd, dus er hoort niets meer achter te staan dan het label zelf."""
versie = _regel_van("ARG SU_VERSION")
for later in ("apt-get update", "download.docker.com", "static/vendor",
"COPY server-up/ ./", "ENTRYPOINT"):
assert _regel_van(later) < versie, \
f"'{later}' staat ná ARG SU_VERSION en wordt dus elke release herbouwd"
def test_de_frontendbestanden_worden_niet_door_de_broncode_overschreven():
"""Ze komen nu vóór `COPY server-up/`. Dat mag alleen als daar geen eigen
static-map in zit, want anders zou die de gedownloade bestanden vervangen."""
assert not (WORTEL / "server-up" / "static").exists(), (
"server-up/static bestaat nu wél; zet de downloads dan weer ná de COPY "
"of geef ze een andere plek")
def test_de_gepinde_versies_staan_er_nog():
"""De cache blijft alleen staan zolang deze regels niet wijzigen — dus als
ze veranderen hoort dat een bewuste keuze te zijn."""
tekst = "\n".join(REGELS)
for gepind in ("@mdi/font@7.4.47", "alpinejs@3.14.1", "htmx.org@2.0.3",
"tailwindcss.com/3.4.16", "docker-27.5.1.tgz", "compose/releases/download/v2.32.4"):
assert gepind in tekst, f"versie niet meer vastgezet: {gepind}"