No description
  • Makefile 60.7%
  • Go Template 39.3%
Find a file
2026-07-04 22:11:03 +02:00
templates fix: increate dockerk8s version 2026-07-04 22:10:58 +02:00
.helmignore initial import 2026-06-25 07:37:28 +02:00
Chart.yaml chore: bump chart to 1.10.0 2026-07-04 22:11:03 +02:00
CLAUDE.md fix: add better job isolation in PVC volume 2026-07-04 16:51:30 +02:00
Makefile feat: add better registration process and configmap override 2026-06-25 08:40:16 +02:00
README.md fix: increate dockerk8s version 2026-07-04 22:10:58 +02:00
values.yaml fix: increate dockerk8s version 2026-07-04 22:10:58 +02:00

forge-runner-k8s Helm Chart

Deploys a Forgejo Actions runner on Kubernetes. CI jobs run as short-lived Pods rather than Docker containers; image builds are handled by a rootless BuildKit sidecar.

Prerequisites

  • Kubernetes cluster with a ReadWriteMany StorageClass (NFS, CephFS, etc.)
  • Helm 3.8+
  • Forgejo instance with Actions enabled

1 — Register the runner on the Forgejo server

Run the following on the host where Forgejo is installed. This pre-registers the runner and emits the credentials you will pass to the chart.

forgejo forgejo-cli actions register

The command prints a UUID and a 40-character hex token. Keep both — you need them in the next step.

Alternatively, generate the registration from the Forgejo web UI: Site Administration → Runners → Create new runner (or the equivalent repo/org settings page).

2 — Install the chart

Create a values file (keep it out of version control):

# my-values.yaml
forgejo:
  instanceUrl: "https://git.example.com"
  runner:
    connection:
      uuid: "<uuid from step 1>"
      token: "<token from step 1>"

dockerk8s:
  registry: "registry.example.com/ci"
  registryPushSecret: "registry-push-secret"   # pre-existing dockerconfigjson Secret

persistence:
  storageClass: "nfs-rwx"

Then install:

helm install my-runner . -f my-values.yaml -n ci --create-namespace

Check the runner pod comes up:

kubectl -n ci get pods
kubectl -n ci logs deploy/my-runner-forge-runner -c runner

The runner should appear as online in the Forgejo runners list within a few seconds.

Key values reference

Value Required Description
forgejo.instanceUrl yes URL of the Forgejo instance
forgejo.runner.connection.uuid yes UUID from forgejo-cli actions register
forgejo.runner.connection.token yes 40-char hex token from the same command
dockerk8s.registry yes Registry prefix for images built by CI jobs
dockerk8s.registryPushSecret for builds dockerconfigjson Secret for push auth
dockerk8s.imagePullSecrets if private images Comma-separated pull secret names for job Pods
dockerk8s.build.enabled no Expose a restricted, docker build-only Docker API listener to CI job Pods (via a ClusterIP Service + NetworkPolicy carve-out); no separate docker push needed, builds push automatically
persistence.storageClass yes Must support ReadWriteMany
networkPolicy.enabled no Isolate the runner pod and CI job pods
dockerk8s.jobIsolation.mountReservedDirs no PVC directories (cache, builds) a job mount can never reach — see CLAUDE.md
dockerk8s.jobIsolation.fsGroup no fsGroup applied to job Pods; not a read-isolation boundary between jobs
dockerk8s.jobIsolation.workspaceCleanup no Remove a job's workspace directory once no container still references it
dockerk8s.jobResources.requests.cpu/.memory no Default CPU/memory request applied to a job Pod when the job didn't request one
dockerk8s.jobResources.limits.cpu/.memory no Default CPU/memory limit applied to a job Pod when the job didn't request one
dockerk8s.jobResources.max.cpu/.memory no Absolute CPU/memory limit ceiling; a resolved value above this is clamped down to it

Note on multi-tenancy: the shared PVC and jobIsolation settings reduce blast radius between jobs but do not provide hard read-isolation on their own (all job Pods share one PVC and commonly run as the same UID). For multi-tenant environments, install one release — its own namespace and PVC — per tenant.

Upgrade

helm upgrade my-runner . -f my-values.yaml -n ci

Uninstall

helm uninstall my-runner -n ci

The PVC is not deleted automatically. Remove it manually if no longer needed:

kubectl -n ci delete pvc my-runner-forge-runner