railiance-forge/docs/forgejo-actions-runner-substrate.md
tegwick a15fac8e93
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
security: verify runner listener closure and post-change CI
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a1346b-72a4-7d40-b8bd-8b8ca346cfa2
2026-10-13 18:50:03 +02:00

3.8 KiB

Forgejo Actions Runner Substrate

Last reviewed: 2026-07-03

Status: in-cluster runner on railiance01 (ADR-004). Supersedes interim coulombcore host runner.

Purpose

Forge-owned Actions runner for https://forgejo.coulomb.social so coulomb organization repos build and publish without workstation or legacy-host Docker. Label contract aligns with docs/gitea-actions-runner-substrate.md and docs/ci-runner-actions-gitops-ownership.md.

Production Runner (ADR-004)

Field Value
Runner name railiance01-build-01
Scope coulomb organization
Placement forgejo namespace, railiance01 k3s
Manifest railiance-apps/manifests/forgejo-runner.yaml
Images code.forgejo.org/forgejo/runner:6.3.1, docker:27-dind
Job runtime DinD sidecar (DOCKER_HOST=tcp://127.0.0.1:2375)
State PVC forgejo-runner-data
Cluster deploy authority Not included

Labels

self-hosted:host,linux:host,linux_amd64:host,container-build:host,registry-publish:host,railiance01:host,ubuntu-latest:docker://node:20-bookworm,docker:docker://node:20-bookworm

Operator Commands

# S5 deploy (railiance-apps)
cd ~/railiance-apps
make forgejo-runner-registration-deploy   # after SOPS encrypt
make forgejo-runner-deploy
make forgejo-runner-status

# Endpoint smoke
make forgejo-smoke

# Generate registration token (in cluster; do not log token)
KUBECONFIG=~/.kube/config-hosteurope kubectl exec -n forgejo deploy/forgejo-gitea -- \
  forgejo actions generate-runner-token --scope coulomb

Secret Boundaries

  • forgejo-runner-registration Kubernetes Secret — registration token only.
  • Repo/org registry credentials — Forgejo Actions secrets, not in Git.
  • No kubeconfig or OpenBao tokens on the runner pod by default.

Retired: Interim coulombcore Host Runner

railiance-coulombcore-build-01 on coulombcore was a scheduling proof only. Disable after in-cluster runner is healthy:

ssh coulombcore 'sudo systemctl disable --now forgejo-runner'

Evidence

  • Host probe (2026-07-03): coulomb/forgejo-actions-probe workflow success.
  • In-cluster (2026-07-03): railiance01-build-01 2/2 Ready; container-probe and image-build workflows success. Image-build uses static docker-cli on the non-root runner host + DOCKER_HOST=tcp://127.0.0.1:2375 (DinD); org secrets REGISTRY_USER / REGISTRY_TOKEN; pushes to forgejo.coulomb.social/coulomb/forgejo-actions-probe.
  • actions/checkout@v4 failed on the host runner — use git clone in job steps until checkout action compatibility is confirmed.

References

October 13 Docker listener hardening

Source railiance-apps 706461b pins the exact previously running image digests and binds Docker to 127.0.0.1:2375; DinD readiness now uses a local exec ping. No resource, replica, registration, credential or PVC change was made. Native generation 4 is Ready: local ping succeeds, other-pod ping refuses and the actual socket is loopback only. Runner heartbeat resumed. The normal source push ran CI workflow 7251 successfully, including host-smoke and container-smoke.

This closes the reproduced unauthenticated cross-pod daemon exposure. Host-mode jobs still share the privileged runner boundary; workflow authority, required secret checks and job credential isolation remain FORGE-WP-0006-T03 work. Exact proposal, retained preflight refinement and guarded rollback: Custodian docs/changes/CUST-WP-0080/forge-runner-loopback-operations.md. Native receipts: docs/evidence/2026-10-13-netkingdom-security/forge-runner-loopback-activation.json and forge-runner-post-change-ci.json.