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.
This commit is contained in:
Esa Kataja
2026-09-05 15:02:35 +03:00
parent fd5b4d212c
commit 522827879b
2 changed files with 6 additions and 2 deletions
+5 -1
View File
@@ -42,10 +42,14 @@ run: build
# out of this file: pass it in, or put it in the .env this reads nothing from. # 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 # 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: image:
@test -n "$(IMAGE)" || { echo "set IMAGE, e.g. make image IMAGE=registry.example.com/owner/levyraati26-go"; exit 1; } @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; }; \ @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" echo "built $(IMAGE):$$v — push with: podman push $(IMAGE):$$v"
# Operations against the running container, straight out of docs/deployment.md. # Operations against the running container, straight out of docs/deployment.md.
+1 -1
View File
@@ -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 | | Uploads fail near 50 MB | The reverse proxy's body limit, not the app's |
| Invite links are relative | `PUBLIC_URL` unset | | Invite links are relative | `PUBLIC_URL` unset |
| Everything 500s after a restore | `-wal`/`-shm` sidecars from the replaced database were left in place | | 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 <code>` — one line, with the stage, the submission id, the URL and the tool's stderr | | A submitter reports a *virhekoodi* | `docker compose logs app \| grep <code>` — 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 | | `/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 | | Setting `ADMIN_PASSWORD` again changes nothing | Seeding only fires on an empty `users` table. Reset the hash in the database instead |