diff --git a/templates/adventurelog/.felhom.yml b/templates/adventurelog/.felhom.yml index cb7f335..9fc7623 100644 --- a/templates/adventurelog/.felhom.yml +++ b/templates/adventurelog/.felhom.yml @@ -10,7 +10,7 @@ subdomain: "travel" slug: "adventurelog" # catalog_since: the date THIS repo last changed this app's pinned images. Any commit that # changes an image: line must set this to the same day (see CLAUDE.md). -catalog_since: "2026-07-18" +catalog_since: "2026-09-27" # --- Resource hints (displayed on deploy screen) --- resources: @@ -110,3 +110,9 @@ i18n: label: 'Database password' - env_var: SECRET_KEY label: 'Encryption key' + +# update_ladder — the test record: one tested step per line, oldest first (JSON flow mappings, +# `09-update-architecture.md` §6.4 part 4). WRITTEN BY scripts/upgrade-test.py, never by hand; +# gated by scripts/check-test-record.py. An image: move without a proven entry here is refused. +update_ladder: + - {"from": {"adventurelog": "ghcr.io/seanmorley15/adventurelog-backend:v0.12.1", "adventurelog-postgres": "postgis/postgis:16-3.5-alpine", "adventurelog-frontend": "ghcr.io/seanmorley15/adventurelog-frontend:v0.12.1"}, "to": {"adventurelog": "ghcr.io/seanmorley15/adventurelog-backend:v0.13.0", "adventurelog-postgres": "postgis/postgis:16-3.5-alpine", "adventurelog-frontend": "ghcr.io/seanmorley15/adventurelog-frontend:v0.13.0"}, "digest": {"adventurelog": "sha256:0250d9cb0d745a8d768f31d3cdc68ac14bfa8b43dedfe0f550158e3861c12db7", "adventurelog-frontend": "sha256:51ee22428b4192f4372b54f84c8b90cd710311ad99993c5045f53b51717dd3f7", "adventurelog-postgres": "sha256:47e961a569fd52ff31f0fe205ed91eeab17d9f5fff6722e6d7ea6b588748b293"}, "verdict": "proven", "tested_at": "2026-09-27T10:29:35Z", "harness_version": 4, "evidence": "felhom.eu/documentation/audits/version-travel-2026-09-26/C/apps/adventurelog/bench/evidence/MV-adventurelog/verdict.json", "box_evidence": "felhom.eu/documentation/audits/version-travel-2026-09-26/C/apps/adventurelog/box/box-verdict-adventurelog.json", "memory_peak_pct": 73.0, "marks": {"files_may_change": false, "needs_person": null, "memory_tight": false}, "memory_basis": "anon", "memory_cgroup_peak_pct": 100.0} diff --git a/templates/adventurelog/docker-compose.yml b/templates/adventurelog/docker-compose.yml index eaff907..a77091b 100644 --- a/templates/adventurelog/docker-compose.yml +++ b/templates/adventurelog/docker-compose.yml @@ -10,7 +10,7 @@ services: adventurelog: - image: ghcr.io/seanmorley15/adventurelog-backend:v0.12.1 + image: ghcr.io/seanmorley15/adventurelog-backend:v0.13.0 container_name: adventurelog restart: unless-stopped depends_on: @@ -30,6 +30,25 @@ services: - PUBLIC_URL=https://${SUBDOMAIN}.${DOMAIN} - CSRF_TRUSTED_ORIGINS=https://${SUBDOMAIN}.${DOMAIN} - FRONTEND_URL=https://${SUBDOMAIN}.${DOMAIN} + # `09` §3 decision 41 (R-655): the world-data download stays. v0.13.0 runs `download-countries` at EVERY + # start and fetches only when the file is ABSENT — a cut-off file from an interrupted download (v0.12.1 + # ignored such failures) makes every start fail with `IncompleteJSONError`. Before the image's own + # entrypoint, a file that does not parse to its end is SET ASIDE (renamed, never deleted), so the + # command downloads it again. The same entrypoint and command as the image's (both versions, measured). + entrypoint: + - /bin/bash + - -c + - | + for f in /code/media/countries+regions+states-*.json; do + [ -s "$$f" ] || continue + if ! python3 -c 'import ijson,sys; [0 for _ in ijson.items(open(sys.argv[1],"rb"),"item")]' "$$f" 2>/dev/null; then + mv "$$f" "$$f.cutoff-$$(date +%Y%m%d%H%M%S)" + echo "felhom: $$f did not parse to its end - set aside, it is downloaded again" >&2 + fi + done + exec /code/entrypoint.sh "$$@" + - -- + command: ["supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"] volumes: - adventurelog_media:/code/media networks: @@ -88,7 +107,7 @@ services: start_period: 20s adventurelog-frontend: - image: ghcr.io/seanmorley15/adventurelog-frontend:v0.12.1 + image: ghcr.io/seanmorley15/adventurelog-frontend:v0.13.0 container_name: adventurelog-frontend restart: unless-stopped environment: @@ -110,16 +129,10 @@ services: resources: limits: memory: 256M - healthcheck: - # A frontend image distroless: nincs benne shell, wget vagy curl — a node - # bináris is csak abszolút úton érhető el (nem a PATH-on). A korábbi wget - # próba ezért soha nem futott le, a konténer véglegesen unhealthy lett, és - # a Traefik nem irányított rá forgalmat (404 az ügyfélnek). - test: ["CMD", "/nodejs/bin/node", "-e", "fetch('http://127.0.0.1:3000').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"] - interval: 10s - timeout: 5s - retries: 5 - start_period: 20s + # No healthcheck override (R-655): v0.12.1's image has none and keeps node at /nodejs/bin/node only; + # v0.13.0's image brings its own (`node` on the PATH, /usr/bin/node, fetching /health, which needs the + # backend). No single exec path works on both versions (measured 2026-09-27), and the old override + # (/nodejs/bin/node) left v0.13.0 unhealthy forever. volumes: adventurelog_media: