kadenz-ci¶
Custom self-hosted GitHub Actions runner image for the Kadenz CI pool,
published as ghcr.io/kadenz-live/ci.
It bakes the full toolchain that the
kadenz-live/kadenz workflows assume
is pre-installed on a runner labelled kadenz-ci
(runs-on: [self-hosted, Linux, X64, kadenz-ci]), so a CI job behaves
identically whether it lands on a bare-metal / VM runner (systemd-based)
or a Docker runner (containerized, docker-compose based).
It replaces the generic myoung34/github-runner:latest image, which lacks
gitleaks, tflint's download prerequisites, the Playwright/chromium system
libraries, and the native-gem build chain.
Note
No secrets live in this repository — only a Dockerfile, an entrypoint, the build workflow, and these docs.
Image tags¶
The pipeline is SemVer release-managed. The source of truth for the
version is the git tags vX.Y.Z; every build on main (push / daily
schedule / manual dispatch) cuts a new patch and publishes the full tag
set:
ghcr.io/kadenz-live/ci:vX.Y.Z # immutable full version (also a git tag + GitHub Release)
ghcr.io/kadenz-live/ci:X.Y # minor float — auto-updates to the newest patch (Docker runners pin here)
ghcr.io/kadenz-live/ci:X # major float
ghcr.io/kadenz-live/ci:latest # newest release
ghcr.io/kadenz-live/ci:sha-<gitsha> # immutable, pin to an exact commit
Every pushed digest is Cosign keyless-signed — see Supply chain for the verification command.
Quickstart¶
-
Mint a repo-scoped registration token:
-
Start the runner with the docker socket bind-mounted:
-
The runner registers, appears under the repository's Settings → Actions → Runners, and de-registers gracefully on
docker stop(see Security for the token-freshness caveat on long-lived runners).
For production-shaped setups (compose, systemd) see Deployment patterns; for the full environment-variable interface see Configuration.
What's baked in¶
| Component | Version | Why |
|---|---|---|
| actions/runner | 2.335.1 (SHA-256 pinned) |
The runner agent itself. |
| gitleaks | 8.21.2 (SHA-256 pinned) |
Secret-scanning jobs run the binary directly. |
| hcloud CLI | 1.66.0 (SHA-256 pinned) |
IaC workflows shell out to hcloud for server discovery. |
| trivy | 0.72.0 (SHA-256 pinned) |
PATH baseline for aquasecurity/trivy-action (see the caveat in the README). |
| Docker CLI + buildx + compose plugins | apt (noble stable) |
Service containers + image builds; the daemon is host-provided. |
| Node.js | apt (Ubuntu noble) | JS composite actions need a system node. |
| gh CLI | apt (cli/cli upstream) | gh workflow run, Dependabot auto-merge crons. |
| libvips42 | apt | ruby-vips / ActiveStorage image processing. |
Playwright chromium system libs + fonts-liberation |
apt (noble t64 ABI) |
Playwright jobs install chromium without --with-deps. |
| Native-gem build chain | apt | Headers/libs that pg, psych, ffi, nokogiri, bcrypt compile against. |
| Python 3 + pip + venv | apt | In-workflow pip install (ansible-core, ansible-lint). |
jq, unzip, curl, git, ca-certificates |
apt | Generic CI plumbing. |
Ruby, Terraform, tflint, a pinned Node version, ansible-core/-lint, sops,
checkov, cosign, and syft are deliberately not baked — they are provided
per-job by setup-* actions, in-workflow installs, or Docker action
containers. See the
README
for the rationale per tool.