diff --git a/apps/app-forgejo-runner.yaml b/apps/app-forgejo-runner.yaml new file mode 100644 index 0000000..65e6259 --- /dev/null +++ b/apps/app-forgejo-runner.yaml @@ -0,0 +1,18 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: forgejo-runner + namespace: argocd +spec: + project: default + source: + repoURL: git@forgejo.forgejo.svc.cluster.local:basicstack/stack.basicstack.de.git + targetRevision: main + path: apps/forgejo-runner + destination: + server: https://kubernetes.default.svc + namespace: forgejo + syncPolicy: + automated: + prune: true + selfHeal: true diff --git a/apps/forgejo-runner/README.md b/apps/forgejo-runner/README.md new file mode 100644 index 0000000..87f5fda --- /dev/null +++ b/apps/forgejo-runner/README.md @@ -0,0 +1,69 @@ +# 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** +```bash +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: + +```bash +# 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: + +```bash +kubectl apply -f apps/app-forgejo-runner.yaml +``` + +## Runner Configuration + +The runner is configured to: +- Run 2 concurrent jobs +- Use Docker-in-Docker for workflow execution +- Support ubuntu-latest and ubuntu-22.04 labels with Node.js 24 +- Connect to Forgejo at http://forgejo.forgejo.svc.cluster.local:3000 + +## Troubleshooting + +Check runner logs: +```bash +kubectl logs -n forgejo -l app=forgejo-runner -f +``` + +Check if runner is registered: +```bash +kubectl exec -n forgejo deployment/forgejo-runner -- forgejo-runner list +``` diff --git a/apps/forgejo-runner/forgejo-runner-config.yaml b/apps/forgejo-runner/forgejo-runner-config.yaml new file mode 100644 index 0000000..6e90e22 --- /dev/null +++ b/apps/forgejo-runner/forgejo-runner-config.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: forgejo-runner-config + namespace: forgejo +data: + config.yaml: | + log: + level: info + runner: + name: k3s-runner-1 + capacity: 2 + labels: + - "ubuntu-latest:docker://node:24-bookworm" + - "ubuntu-22.04:docker://node:24-bookworm" + timeout: 3h + cache: + enabled: true + dir: /data/cache + container: + network: bridge + privileged: false + options: --user 1000:1000 diff --git a/apps/forgejo-runner/forgejo-runner-deployment.yaml b/apps/forgejo-runner/forgejo-runner-deployment.yaml new file mode 100644 index 0000000..30d4bc6 --- /dev/null +++ b/apps/forgejo-runner/forgejo-runner-deployment.yaml @@ -0,0 +1,74 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: forgejo-runner + namespace: forgejo +spec: + replicas: 1 + selector: + matchLabels: + app: forgejo-runner + template: + metadata: + labels: + app: forgejo-runner + spec: + serviceAccountName: forgejo-runner + containers: + - name: runner + image: code.forgejo.org/forgejo/runner:4.0.1 + imagePullPolicy: IfNotPresent + command: + - sh + - -c + - | + # Wait for Forgejo to be ready + while ! wget -q -O- http://forgejo.forgejo.svc.cluster.local:3000/api/healthz > /dev/null 2>&1; do + echo "Waiting for Forgejo to be ready..." + sleep 5 + done + + # Register runner if not already registered + if [ ! -f /data/.runner ]; then + forgejo-runner register \ + --no-interactive \ + --instance http://forgejo.forgejo.svc.cluster.local:3000 \ + --token "$RUNNER_TOKEN" \ + --name k3s-runner-1 \ + --labels ubuntu-latest:docker://node:24-bookworm,ubuntu-22.04:docker://node:24-bookworm + fi + + # Start runner + forgejo-runner daemon --config /etc/forgejo-runner/config.yaml + env: + - name: RUNNER_TOKEN + valueFrom: + secretKeyRef: + name: forgejo-runner-token + key: token + - name: DOCKER_HOST + value: unix:///var/run/docker.sock + volumeMounts: + - name: docker-sock + mountPath: /var/run/docker.sock + - name: runner-data + mountPath: /data + - name: config + mountPath: /etc/forgejo-runner + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: "2" + memory: 2Gi + volumes: + - name: docker-sock + hostPath: + path: /var/run/docker.sock + type: Socket + - name: runner-data + emptyDir: {} + - name: config + configMap: + name: forgejo-runner-config diff --git a/apps/forgejo-runner/forgejo-runner-serviceaccount.yaml b/apps/forgejo-runner/forgejo-runner-serviceaccount.yaml new file mode 100644 index 0000000..550a8c4 --- /dev/null +++ b/apps/forgejo-runner/forgejo-runner-serviceaccount.yaml @@ -0,0 +1,29 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: forgejo-runner + namespace: forgejo +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: forgejo-runner + namespace: forgejo +rules: +- apiGroups: [""] + resources: ["pods", "pods/log"] + verbs: ["get", "list", "watch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: forgejo-runner + namespace: forgejo +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: forgejo-runner +subjects: +- kind: ServiceAccount + name: forgejo-runner + namespace: forgejo