Skip to content

github-runner

Recipe card from the charly-distros plugin (Images — the deployable catalog).

github-runner – GitHub Actions self-hosted runner

Section titled “github-runner – GitHub Actions self-hosted runner”
Property Value
Dependencies supervisord, container-nesting
Volume state -> ${HOME}/actions-runner
Service github-runner (supervisord; runs run.sh as uid 1000)
Security none of its own — rootless nested podman comes from container-nesting (no privileged)
Install files task: — declarative pinned download: of the runner tarball + write: of the ghcr mirror config; the runner tree is root-extracted (the shared download cache is root-owned) then chown -Red to uid 1000 (the one ownership cmd:)

Packages (distro.arch, all in the official core/extra repos)

Section titled “Packages (distro.arch, all in the official core/extra repos)”
  • Toolchain: jq, git, go, cloud-guest-utils, cosign
  • Cross-arch CI: qemu-user-static, qemu-user-static-binfmt (aarch64 binfmt)
  • .NET runtime deps for the runner binary (its installdependencies.sh has no Arch branch): icu, krb5, openssl, libunwind, lttng-ust (NOT zlib — CachyOS ships zlib-ng-compat, which Provides it; an explicit zlib conflicts)
  • charly-host depends= completion: slirp4netns, libisoburn, cdrtools, swtpm — the part of the charly package’s depends= set (packaging.formats.archlinux.depends in the charly candy) the charly/virtualization candies do not already install, so the charly CLI (and the CI jobs that drive it) runs fully on the runner. (The legacy charly box pkg release-packages build that ran here is removed with the nFPM cutover — the charly generate-packages plugin + the per-distro repos build the packages now.)

podman/buildah/skopeo/crun/fuse-overlayfs are provided by the container-nesting dependency (not redeclared here — R3).

Variable Mechanism
RUNNER_ORG env_accept (plaintext identifier; supplied at deploy)
RUNNER_TOKEN secret_accept (credential-store-backed; never in charly.yml/quadlet)
RUNNER_WORK_DIR ${HOME}/actions-runner/_work
RUNNER_GROUP Default

The runner installs under ${HOME}/actions-runner and runs as uid 1000. The ghcr.io pull-through mirror (127.0.0.1:5000) config is written to the user location ${HOME}/.config/containers/registries.conf.d/ (rootless podman).

  • post_enable — registers the runner with RUNNER_ORG + RUNNER_TOKEN. Skips (no-op) when RUNNER_TOKEN is empty — so a token-less deploy (an check bed) brings the image up without registering.
  • pre_remove — deregisters; needs a remove-token (distinct from the registration token). Also skips when the token is empty.
# charly.yml — rootless, CachyOS
githubrunner:
base: cachyos.cachyos
build: [pac]
candy: [agent-forwarding, github-runner, charly, dbus, container-nesting]
network: host # no uid/privileged override → rootless
Terminal window
TOKEN=$(gh api -X POST /orgs/myorg/actions/runners/registration-token --jq .token)
charly config githubrunner -e RUNNER_ORG=myorg -e RUNNER_TOKEN="$TOKEN"
charly remove githubrunner -e RUNNER_TOKEN=$(gh api -X POST /orgs/myorg/actions/runners/remove-token --jq .token)

Use when the user asks about:

  • GitHub Actions self-hosted runners
  • Runner registration or deregistration
  • CI/CD container infrastructure
  • RUNNER_TOKEN or RUNNER_ORG configuration