From 522827879b12420e96393997661602b1cb160c73 Mon Sep 17 00:00:00 2001 From: Esa Kataja Date: Sat, 5 Sep 2026 15:02:35 +0300 Subject: [PATCH] Build release images without the layer cache A submission failed with HTTP 403 against a freshly published image. The cause was not Alpine, which carries the current yt-dlp: it was the apk layer being reused from an older build, so the image shipped a yt-dlp two months behind while /healthz reported today's tag. "A rebuild is the update" only holds if the layer is genuinely re-run, so the image target now passes --pull --no-cache. Slower, and the only thing that makes the release honest about what is inside it. --- Makefile | 6 +++++- docs/deployment.md | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index c236c7f..d7c16d8 100644 --- a/Makefile +++ b/Makefile @@ -42,10 +42,14 @@ run: build # out of this file: pass it in, or put it in the .env this reads nothing from. # # make image IMAGE=registry.example.com/owner/levyraati26-go +# +# --pull --no-cache is the point of the target, not caution. yt-dlp rots against YouTube within +# weeks, and "a rebuild is the update" is only true if the apk layer is actually re-run — a cached +# one silently ships whatever yt-dlp was current the day that layer was first built. image: @test -n "$(IMAGE)" || { echo "set IMAGE, e.g. make image IMAGE=registry.example.com/owner/levyraati26-go"; exit 1; } @v=$$(git describe --tags --exact-match 2>/dev/null) || { echo "HEAD is not tagged; tag the release first"; exit 1; }; \ - podman build --build-arg VERSION=$$v -t $(IMAGE):$$v -t $(IMAGE):latest . && \ + podman build --pull --no-cache --build-arg VERSION=$$v -t $(IMAGE):$$v -t $(IMAGE):latest . && \ echo "built $(IMAGE):$$v — push with: podman push $(IMAGE):$$v" # Operations against the running container, straight out of docs/deployment.md. diff --git a/docs/deployment.md b/docs/deployment.md index 9ffece9..3ad7e9c 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -269,7 +269,7 @@ bounded by the two conversion slots. | Uploads fail near 50 MB | The reverse proxy's body limit, not the app's | | Invite links are relative | `PUBLIC_URL` unset | | Everything 500s after a restore | `-wal`/`-shm` sidecars from the replaced database were left in place | -| Submissions all fail at download | yt-dlp is stale, or YouTube is refusing this server's IP; rebuild and publish the image first. `docker compose logs app \| grep '"stage":"download"'` shows yt-dlp's own stderr under `detail` | +| Submissions all fail at download | yt-dlp is stale, or YouTube is refusing this server's IP. `docker compose logs app \| grep '"stage":"download"'` shows yt-dlp's own stderr under `detail`. A plain `HTTP Error 403` is the stale case — rebuild with `make image`, which forces `--no-cache` so the `apk add` layer is genuinely re-run. A `docker build` without it can ship a months-old yt-dlp from a cached layer | | A submitter reports a *virhekoodi* | `docker compose logs app \| grep ` — one line, with the stage, the submission id, the URL and the tool's stderr | | `/admin` returns 404 while logged in | That account has no `is_admin`. Set it in the database; nothing in the UI grants it | | Setting `ADMIN_PASSWORD` again changes nothing | Seeding only fires on an empty `users` table. Reset the hash in the database instead |