Publishing this image by hand hit four obstacles in a row, each of which
recurs on every rebuild:
413 Payload Too Large gitea.langenoja.se is behind Cloudflare, which
caps request bodies below a registry layer
Docker Hub auth refusal the bare MagicDNS name was parsed as a Docker Hub
NAMESPACE — a registry host is only recognised
when it contains a dot or a colon
insufficient_scope the PAT needs write:package, not read:package
wrong-arch pulls forgejo-runner runs on arm64 and zegit-runner on
amd64, neither pins a nodeSelector, and both use
this one tag
The image reference must keep the hostname gitea.langenoja.se, because that is
what the cluster pulls. So the script keeps the NAME and changes only the
ROUTE: it pins that hostname to the Istio gateway on the LAN for the duration
of the push. The gateway serves a *.langenoja.se wildcard cert, so TLS
validates normally — no insecure-registries needed.
The pin carries a marker comment, which makes three cases distinguishable: a
leftover from a run that died before its trap fired (reuse, then remove), a
pin the operator added deliberately (never touch), and one pointing somewhere
other than the gateway (refuse to run). Without the marker a leftover pin was
indistinguishable from a deliberate one, so it survived every later run and
had to be reverted by hand. `--unpin` clears a leftover without building, and
the trap covers INT and TERM as well as EXIT.
It also verifies the published manifest really lists two architectures rather
than trusting the push's exit code.
Alpine splits git-http-backend OUT of the `git` package: git alone ships
git-remote-http/https but not the CGI backend. The runner therefore had git
2.52.0 and no git-http-backend, so zegit's internal/forgeprobe smart-HTTP tests
failed at request time with "fork/exec git-http-backend: no such file or
directory" and reported three FAILURES for a missing tool.
That turned Gitea CI red on every zegit master commit while GitHub stayed
green, for hours, with nobody looking — GitHub is the release oracle, which is
exactly why a red mirror is invisible.
Verified against the real base image, not just alpine:3 — on
code.forgejo.org/forgejo/runner:12.11.1 (Alpine 3.23), `apk add git git-daemon`
puts git-http-backend at /usr/libexec/git-core/git-http-backend, and
`git --exec-path` resolves to that directory, which is the lookup the test
harness performs.
Adds the Dockerfile (FROM code.forgejo.org/forgejo/runner:12.11.1, plus
node/git/bash/coreutils/curl/tar/make/ca-certificates) and a README with
the multi-arch build/push workflow. Built and pushed as
gitea.langenoja.se/zegit-zoo/zegit-forgejo-runner:12.11.1-ci; consumed by
flux-config applications/forgejo-runner.
Co-Authored-By: Claude Opus 4.8 <[email protected]>