stack.basicstack.de/apps/forgejo-runner/README.md
CTO 8dffba2c52 fix(forgejo-runner): pin to nodes with docker installed (DEV-498)
Rolling OS updates removed docker.io from all workers, breaking the
runner's hostPath mount of /var/run/docker.sock (type=Socket check).

- Install docker.io on all 5 worker nodes and enable the systemd unit.
- Label the nodes basicstack.de/docker=true so the dependency is explicit.
- Add nodeSelector to the Deployment so scheduling fails fast on
  non-labeled nodes instead of hanging in ContainerCreating.
- Document the node prerequisite in the README.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-08-16 20:15:16 +00:00

3.3 KiB

Forgejo Actions Runner

This directory contains the deployment configuration for the Forgejo Actions runner.

Prerequisites

Before deploying the runner, you need to obtain a registration token from Forgejo.

Getting the Registration Token

Option 1: Via Forgejo Admin UI

  1. Log in to https://forgejo.basicstack.de as admin
  2. Navigate to Site Administration → Actions → Runners
  3. Click "Create new Runner"
  4. Copy the registration token

Option 2: Via API

export FORGEJO_TOKEN="your-api-token"
curl -X POST \
  -H "Authorization: token $FORGEJO_TOKEN" \
  https://forgejo.basicstack.de/api/v1/admin/runners/registration-token

Creating the Secret

Once you have the registration token, create a sealed secret:

# Create a temporary secret file
kubectl create secret generic forgejo-runner-token \
  --from-literal=token='YOUR_REGISTRATION_TOKEN' \
  --namespace=forgejo \
  --dry-run=client -o yaml > /tmp/runner-token-secret.yaml

# Seal it with kubeseal
kubeseal --format=yaml < /tmp/runner-token-secret.yaml > apps/forgejo-runner/forgejo-runner-token-sealed.yaml

# Clean up
rm /tmp/runner-token-secret.yaml

Deployment

The runner is deployed via Argo CD. After creating the sealed secret, apply the Argo CD application:

kubectl apply -f apps/app-forgejo-runner.yaml

Runner Configuration

The runner is deployed as a Deployment (single replica) that bind-mounts the host's /var/run/docker.sock to execute job containers. This requires the Docker Engine (package docker.io) to be installed and running on the target node — see Node prerequisites below.

Configuration:

  • Deployment type: Deployment (replicas=1)
  • Docker execution: Host Docker socket (/var/run/docker.sock)
  • Concurrent jobs: 2 (configurable via config.yaml)
  • Labels: ubuntu-latest:docker://node:24-bookworm, ubuntu-22.04:docker://node:24-bookworm
  • Forgejo URL: https://forgejo.basicstack.de (external URL for proper webhook/API access)
  • Node selector: basicstack.de/docker=true — schedules only on nodes with the Docker Engine installed. See Node prerequisites below.

Node prerequisites (required)

The runner uses the host's Docker daemon. Every worker node that should be eligible to run the runner MUST have docker.io installed, the docker systemd unit enabled, and be labeled basicstack.de/docker=true. Bootstrap a worker with:

ssh root@<node>
DEBIAN_FRONTEND=noninteractive apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y docker.io
systemctl enable --now docker
# from the control plane:
kubectl label node <node-name> basicstack.de/docker=true --overwrite

Rolling OS updates that reimage a node will remove Docker. Re-run the bootstrap after any node reimage. Without Docker, the runner pod fails to mount /var/run/docker.sock (hostPath type check for Socket fails); the nodeSelector prevents that scheduling mistake by pinning to labeled nodes.

Troubleshooting

Check runner logs:

kubectl logs -n forgejo -l app=forgejo-runner -f

Check if runner is registered:

kubectl exec -n forgejo deployment/forgejo-runner -- forgejo-runner list

Kubernetes native runners

Kubernetes native runner still in discussion / under construction:\ https://codeberg.org/forgejo/discussions/issues/66