feat: custom toolchain image for host-mode Gitea Actions runner

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]>
This commit is contained in:
markusandClaude Opus 4.8 committed 2026-06-16 11:54:04 +02:00
commit 9886437b2f
2 files changed
+82

No files matched your search

+43
View File
@@ -0,0 +1,43 @@
# 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
# 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
#
# 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 \
bash \
coreutils \
curl \
tar \
make \
ca-certificates
# Match the runner pod's runAsUser (1000); keep the image non-root by default.
USER 1000
+39
View File
@@ -0,0 +1,39 @@
# zegit-forgejo-runner
Custom toolchain image for the cluster's self-hosted **Gitea Actions (Forgejo)
runner**, which runs in *host mode* (Docker disabled) — workflow steps execute
inside this image, so it must carry node/git/make/etc. that the stock
`code.forgejo.org/forgejo/runner` image lacks.
This repo lives only on Gitea (`zegit-zoo/zegit-forgejo-runner`). The cluster-side
deployment and rationale live in `flux-config` (`runners.md`,
`applications/forgejo-runner/`).
## Build & push
The runner needs this image to run *any* job, so the **first** build must be done
by hand (CI can't bootstrap itself). The cluster is mixed amd64/arm64, so build
multi-arch:
```sh
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 .
```
The Gitea package is **public**, so the `forgejo-runner-system` namespace pulls it
without an imagePullSecret.
## Wire it into the cluster
After the push succeeds, in `flux-config`
`applications/forgejo-runner/base/deployment-forgejo-runner.yaml` set the `image:`
on **both** the `register` initContainer and the `forgejo-runner` daemon to
`gitea.langenoja.se/zegit-zoo/zegit-forgejo-runner:12.11.1-ci`, then commit (Flux
reconciles). Do this only *after* the image exists, or the pod ImagePullBackOffs.
## Tag scheme
`<base-runner-version>-ci` (e.g. `12.11.1-ci`). Must satisfy the cluster's
Gatekeeper `enforce-semantic-image-tags` constraint — never `:latest`.