REGRESSION, mine. The committed Dockerfile had drifted from the image actually
in service: the running ci3 image contained these four packages, the Dockerfile
did not, and I rebuilt ci4 from the Dockerfile. The rollout therefore removed
tools zegit's CI depends on.
Proof the deployed ci3 had them: its Gitea runs got PAST `make credentials-check`
— which shells out to python3 — and failed later at cover-check. The ci4 run
fails earlier, at `credentials-coverage: need python3`.
What each is for, so the next rebuild does not drop them again:
python3, py3-yaml the repo's own gates are Python — credentials-coverage.sh,
validate-admission.sh and feature-lint.sh all shell out to
it, and credentials-coverage parses manifests with yaml
gcc, musl-dev cgo, which `go test -race` in the Makefile test target
requires: a C compiler plus libc headers (musl on Alpine)
Verified on the real base image rather than assumed — on
code.forgejo.org/forgejo/runner:12.11.1, `apk add git git-daemon gcc musl-dev
python3 py3-yaml` yields Python 3.12.14, a working `import yaml`, gcc 15.2.0,
and git-http-backend on the git exec path.
The deeper lesson is that a hand-built image can drift from its Dockerfile
silently, and nothing notices until someone rebuilds. Publishing via CI (#2)
is what stops that recurring, since every future image comes from the
committed file.
62 lines
2.8 KiB
Docker
62 lines
2.8 KiB
Docker
# Custom toolchain image for the self-hosted Gitea Actions (Forgejo) runner.
|
|
#
|
|
# The cluster runs act_runner in *host mode* (docker disabled), so workflow steps
|
|
# execute INSIDE this image. The stock forgejo/runner image is minimal and lacks
|
|
# node (needed by JS actions: actions/checkout, setup-go, ...), git, make, etc.
|
|
# The runner pod is non-root with all caps dropped, so it cannot apt/apk-add at
|
|
# runtime -- the tools must be baked in here.
|
|
#
|
|
# Build multi-arch (cluster is mixed amd64/arm64) and push to the Gitea registry:
|
|
#
|
|
# docker buildx create --use --name zegit-ci 2>/dev/null || true
|
|
# docker login gitea.langenoja.se # username + a Gitea personal access token
|
|
# docker buildx build --platform linux/amd64,linux/arm64 \
|
|
# -t gitea.langenoja.se/zegit-zoo/zegit-forgejo-runner:12.11.1-ci --push .
|
|
#
|
|
# Then in flux-config set both containers' image: to the tag above and commit.
|
|
# Package visibility is PUBLIC, so the runner namespace pulls without a secret.
|
|
FROM code.forgejo.org/forgejo/runner:12.11.1
|
|
|
|
USER root
|
|
|
|
# nodejs -> JS actions runtime (actions/checkout, actions/setup-go, ...)
|
|
# git -> checkout
|
|
# git-daemon -> provides git-http-backend, which Alpine splits OUT of the `git`
|
|
# package (git alone ships git-remote-http/https but NOT the CGI
|
|
# backend). Without it, internal/forgeprobe's smart-HTTP tests died
|
|
# with "fork/exec git-http-backend: no such file or directory" and
|
|
# reported three FAILURES for a missing tool — which turned Gitea CI
|
|
# red on every zegit master commit while GitHub stayed green, for
|
|
# hours, unnoticed.
|
|
# bash -> `shell: bash` steps and many action entrypoints
|
|
# coreutils-> GNU userland (alpine busybox tools trip up some scripts)
|
|
# curl,tar -> setup-go / gitleaks download + extract their own arch-specific binaries
|
|
# make -> zegit Makefile targets
|
|
# ca-certificates -> trusted roots for HTTPS to gitea/github/goproxy
|
|
# gcc,musl-dev -> C toolchain for cgo; `go test -race` (the Makefile test
|
|
# target) requires cgo, which needs a C compiler + libc headers
|
|
# (musl on Alpine)
|
|
# python3,py3-yaml -> the repo's own gates are Python: credentials-coverage.sh,
|
|
# validate-admission.sh and feature-lint.sh all shell out to
|
|
# python3, and credentials-coverage parses manifests with yaml
|
|
#
|
|
# Go is intentionally NOT baked in: actions/setup-go fetches the pinned version
|
|
# per-run (node + tar are present), so the image needs no rebuild on Go bumps.
|
|
RUN apk add --no-cache \
|
|
nodejs \
|
|
git \
|
|
git-daemon \
|
|
bash \
|
|
coreutils \
|
|
curl \
|
|
tar \
|
|
make \
|
|
ca-certificates \
|
|
gcc \
|
|
musl-dev \
|
|
python3 \
|
|
py3-yaml
|
|
|
|
# Match the runner pod's runAsUser (1000); keep the image non-root by default.
|
|
USER 1000
|