ARC Runner
Overview
Section titled “Overview”arc-runner is the custom Actions Runner Controller image consumed by the arc-runner-set scale set in the arc-runners namespace. It layers a small bundle of build tooling on top of ghcr.io/actions/actions-runner so CI jobs do not have to apt-get install the same packages on every cold start.
Why a custom image
Section titled “Why a custom image”Workflows that run on arc-runner-set currently install git-lfs, unzip, and similar tools as the first step of every job. The Unity build matrix in ci-unity.yml re-installs git-lfs once per build target — three installs per workflow run today, more as we add Unity targets. Cumulatively this adds minutes of wall-clock time to every Unity matrix and burns ARC pod CPU on apt repo round-trips that are identical across runs.
A baked image fixes the pattern in three ways:
- No cold-start
apt-get— every tool the runner pool needs is onPATHthe moment the runner pod starts. - Air-gap-safe under apt mirror outages — image dependencies are pinned via the upstream
actions-runnertag plusaptsnapshots; a transientarchive.ubuntu.comoutage no longer fails Unity matrix legs. - Single source of truth — bumping a tool happens once in this Dockerfile + version, not in every workflow that references it.
Image layout
Section titled “Image layout”| Binary | Purpose |
|---|---|
actions-runner | Upstream GitHub Actions self-hosted runner (/home/runner/run.sh) |
git-lfs | Forgejo LFS pulls (rareicon Unity, future chuck UE5) |
unzip | butler installer + generic archive tooling |
jq | Manifest dispatch + workflow shell glue |
xz-utils | .tar.xz extraction (Unity, butler, SDK installers) |
gh | GitHub CLI for workflows that shell out to it |
curl | Inherited from upstream, kept explicit for downstream callers |
ca-certificates | TLS trust for HTTPS-fetched dependencies |
The image runs as the upstream runner user by default. The pod spec sets runAsUser: 0 and the entrypoint hands control to /home/runner/run.sh; a sudoers entry for root is baked in so a future cleanup can drop the inline command: override on arc-runner-set.
Build args
Section titled “Build args”| Arg | Default | Purpose |
|---|---|---|
ACTIONS_RUNNER_VERSION | 2.333.0 | Upstream ghcr.io/actions/actions-runner tag the image is layered onto. Bump to follow upstream minor releases. |
Used by
Section titled “Used by”apps/kube/github/runners/manifests/values.yaml—template.spec.containers[].imageandtemplate.spec.initContainers[].imagewill flip toghcr.io/kbve/arc-runner:<tag>in a follow-up PR. The first publish of this image happens on the upstream runner image; subsequent rebuilds run on the custom image itself.
Rollout sequence
Section titled “Rollout sequence”This page tracks the image artefact only. The full migration runs across three PRs to keep rollback cheap:
- This PR — publish
ghcr.io/kbve/arc-runner:0.1.0via the standardci-docker.ymldispatch path. - Follow-up — flip both
image:references inarc-runner-setvalues.yaml and bump thekbve.com/restart-triggerannotation. - Follow-up — strip the
Install git-lfsstep (and any otherapt-get installband-aids) fromci-unity.ymlonce the new runner pods are confirmed serving jobs.
Version cadence
Section titled “Version cadence”- Track upstream
actions/runnerminor releases inACTIONS_RUNNER_VERSION. Patch bumps can ride along on dependabot. - Every image publish bumps both
version.toml(rebuild trigger via the dispatch manifest) and thekbve.com/restart-triggerannotation in values.yaml (forces a runner pod roll).