Was ist ein Forgejo?

Forgejo ist eine beliebte, quelloffene Git-Hosting-Lösung, die sich hervorragend für Teams eignet, die ihre Infrastruktur lieber selbst verwalten. Seit Einführung von Forgejo Actions ist es möglich, CI/CD-Jobs direkt über Forgejo auszuführen – ähnlich wie bei GitHub Actions.

In diesem Beitrag zeige ich dir, wie du einen Forgejo Runner auf Kubernetes betreibst, der vollständig Docker-fähig ist und sich automatisch bei deiner Forgejo-Instanz registriert.

Ursprung von Forgejo

Forgejo ist ein Fork von Gitea, der aus einer Auseinandersetzung innerhalb der Gitea-Community entstanden ist. Die Hintergründe sind sowohl technisch als auch organisatorisch motiviert. Hier die wichtigsten Punkte zur Entstehung und dem „Warum“:

Gitea war ursprünglich ein Community-getriebener Fork von Gogs und entwickelte sich zu einer beliebten, leichtgewichtigen Git-Hosting-Lösung in Go. Im Jahr 2022 kündigte das Gitea-Projekt an, dass eine neue Firma namens Gitea Ltd. gegründet wurde, um die Weiterentwicklung zu kommerzialisieren. Diese Entscheidung wurde von vielen Mitgliedern der Community kritisch gesehen, vor allem weil:

Als Reaktion darauf wurde Forgejo Ende 2022 als Fork ins Leben gerufen. Ziel war es, die ursprünglichen Ideale von Gitea als gemeinschaftlich entwickeltes, nicht kommerzielles Projekt wiederzubeleben.

Forgejo basiert weiterhin auf Gitea, entwickelt sich aber unabhängig und legt Wert auf:

🚀 Warum ein eigener Runner?

🧩 Architektur des Deployments

Namespace

apiVersion: v1
kind: Namespace
metadata:
name: forgejo-runner

Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
name: forgejo-runner
namespace: forgejo-runner
spec:
replicas: 2
selector:
matchLabels:
app.kubernetes.io/name: forgejo-runner
app.kubernetes.io/part-of: forgejo-runner
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
template:
metadata:
labels:
app.kubernetes.io/name: forgejo-runner
app.kubernetes.io/part-of: forgejo-runner
spec:
restartPolicy: Always
volumes:
- name: docker-certs
emptyDir: {{}}
- name: runner-data
emptyDir: {{}}
- name: runner-config
configMap:
name: forgejo-runner-config
items:
- key: "config.yaml"
path: "config.yaml"
- name: runner-secret
secret:
secretName: runner-secret
initContainers:
- name: runner-register
image: code.forgejo.org/forgejo/runner:7.0.0
command:
- bash
- -c
- |
set -euo pipefail
env
exec forgejo-runner register --no-interactive --token "$(cat "/runner-auth/token")" --name "$RUNNER_NAME" "--instance" "$FORGEJO_INSTANCE_URL"
env:
- name: RUNNER_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: FORGEJO_INSTANCE_URL
value: https://git.bueraner.de
resources:
requests:
cpu: "0.25"
memory: "64Mi"
limits:
cpu: "0.50"
memory: "64Mi"
volumeMounts:
- name: runner-data
mountPath: /data
- name: runner-config
mountPath: /opt
readOnly: true
- name: runner-secret
mountPath: /runner-auth
readOnly: true
containers:
- name: runner
image: code.forgejo.org/forgejo/runner:7.0.0
command: ["sh", "-c", "while ! nc -z localhost 2376 </dev/null; do echo 'waiting for docker daemon...'; sleep 5; done; forgejo-runner daemon --config /opt/config.yaml"]
env:
- name: DOCKER_HOST
value: tcp://localhost:2376
- name: DOCKER_CERT_PATH
value: /certs/client
- name: DOCKER_TLS_VERIFY
value: "1"
volumeMounts:
- name: docker-certs
mountPath: /certs
- name: runner-data
mountPath: /data
- name: runner-config
mountPath: /opt
readOnly: true
- name: daemon
image: code.forgejo.org/oci/docker:dind
env:
- name: DOCKER_TLS_CERTDIR
value: /certs
securityContext:
privileged: true
volumeMounts:
- name: docker-certs
mountPath: /certs

kustomization.yaml

Ich nutze flux um meinen k3s-Cluser zu managen. Hier wird in der kustomization.yaml die values.yaml als configMap zur Verfügung gestellt.

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./namespace.yaml
- ./sealed-secret.yaml
- ./deployment.yaml
configMapGenerator:
- name: forgejo-runner-config
files:
- "config.yaml"
namespace: forgejo-runner

config.yaml

runner:
envs:
DOCKER_HOST: tcp://localhost:2376
DOCKER_TLS_VERIFY: 1
DOCKER_CERT_PATH: /certs/client
labels:
- 'docker:docker://ghcr.io/catthehacker/ubuntu:act-22.04'
- 'self-hosted:host://-self-hosted'
- 'ubuntu-20.04:docker://ghcr.io/catthehacker/ubuntu:act-20.04'
- 'ubuntu-22.04:docker://ghcr.io/catthehacker/ubuntu:act-22.04'
# - 'ubuntu-latest:docker://ghcr.io/catthehacker/ubuntu:act-latest'
- 'runner-20.04:docker://ghcr.io/catthehacker/ubuntu:runner-20.04'
- 'runner-22.04:docker://ghcr.io/catthehacker/ubuntu:runner-22.04'
- 'runner-latest:docker://ghcr.io/catthehacker/ubuntu:runner-latest'
container:
network: host
options: -v /certs/client:/certs/client
valid_volumes:
- /certs/client
docker_host: ""

Secret

HINWEIS Das Secret runner-secret musst du natürlich noch erstellen!

Gemacht mit ❤️ und Astro
© 2025 |
Version: v1.11.2
Impressum
Datenschutz