stack.basicstack.de/apps/forgejo-runner
CTO Agent 27397fe859 feat: migrate Forgejo runner to StatefulSet with Docker-in-Docker
Replaces the Deployment-based runner with a StatefulSet using a proper
Docker-in-Docker sidecar for improved isolation and state management.

Key changes:
- StatefulSet deployment for stable pod identity and persistent storage
- Docker-in-Docker init container (privileged) providing isolated Docker daemon
- Two persistent volumes: runner-data (1Gi) for config, docker-data (20Gi) for image cache
- Uses hcloud-volumes storage class for durability
- Each replica gets its own Docker daemon and image cache

This addresses the workflow failure where job containers (node:24-bookworm)
couldn't access Docker because the CLI was missing. The DinD sidecar provides
a complete Docker environment for all job containers.

Fixes: DEV-335

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-07-18 16:41:20 +00:00
..
forgejo-runner-config.yaml fix: bind-mount host docker binary into job containers 2026-07-18 16:40:32 +00:00
forgejo-runner-serviceaccount.yaml Add Forgejo Actions runner deployment configuration 2026-07-18 14:21:57 +00:00
forgejo-runner-statefulset.yaml feat: migrate Forgejo runner to StatefulSet with Docker-in-Docker 2026-07-18 16:41:20 +00:00
forgejo-runner-token-sealed.yaml feat: add Forgejo runner registration token secret 2026-07-18 15:45:33 +00:00
README.md feat: migrate Forgejo runner to StatefulSet with Docker-in-Docker 2026-07-18 16:41:20 +00:00

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 StatefulSet with Docker-in-Docker (dind) sidecar for proper isolation and state management.

Configuration:

  • Deployment type: StatefulSet (stable pod identity, persistent storage)
  • Docker execution: Docker-in-Docker sidecar (privileged init container)
  • 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)
  • Persistent volumes:
    • runner-data (1Gi): Runner registration and config
    • docker-data (20Gi): Docker image cache

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