From 9bf86e2355650efd557b783c06435f3e2cd0f7b2 Mon Sep 17 00:00:00 2001 From: Nik Afiq Date: Tue, 10 Mar 2026 01:27:48 +0900 Subject: [PATCH] Add Gitea Actions Runner setup with configuration and deployment manifests --- .env.example | 5 +- ansible/playbooks/setup-gitea-runner.yaml | 15 +++ ansible/roles/gitea-runner/handlers/main.yaml | 6 + ansible/roles/gitea-runner/tasks/main.yaml | 104 +++++++++++++++++ manifests/gitea-runner-secret.sh | 13 +++ manifests/gitea-runner.yaml | 105 ++++++++++++++++++ 6 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 ansible/playbooks/setup-gitea-runner.yaml create mode 100644 ansible/roles/gitea-runner/handlers/main.yaml create mode 100644 ansible/roles/gitea-runner/tasks/main.yaml create mode 100644 manifests/gitea-runner-secret.sh create mode 100644 manifests/gitea-runner.yaml diff --git a/.env.example b/.env.example index bfcd36f..73864d6 100644 --- a/.env.example +++ b/.env.example @@ -3,4 +3,7 @@ PORKBUN_API_KEY=pk1_your_key_here PORKBUN_SECRET_KEY=sk1_your_key_here # K3s node token for agent join -K3S_NODE_TOKEN=your_token_here \ No newline at end of file +K3S_NODE_TOKEN=your_token_here + +# Gitea runner token for CI/CD +GITEA_RUNNER_TOKEN=your_token_here \ No newline at end of file diff --git a/ansible/playbooks/setup-gitea-runner.yaml b/ansible/playbooks/setup-gitea-runner.yaml new file mode 100644 index 0000000..04377e8 --- /dev/null +++ b/ansible/playbooks/setup-gitea-runner.yaml @@ -0,0 +1,15 @@ +--- +# Run: ansible-playbook ansible/playbooks/setup-gitea-runner.yaml +# +# What this does: +# - Installs act_runner as a systemd service on Minisforum +# - Registers runner with Gitea + +- name: Deploy Gitea Actions Runner on Minisforum + hosts: minisforum + gather_facts: true + vars: + gitea_runner_token: "{{ lookup('env', 'GITEA_RUNNER_TOKEN') }}" + + roles: + - gitea-runner \ No newline at end of file diff --git a/ansible/roles/gitea-runner/handlers/main.yaml b/ansible/roles/gitea-runner/handlers/main.yaml new file mode 100644 index 0000000..ee619fa --- /dev/null +++ b/ansible/roles/gitea-runner/handlers/main.yaml @@ -0,0 +1,6 @@ +--- +- name: Restart act_runner + ansible.builtin.systemd: + name: act_runner + state: restarted + become: true \ No newline at end of file diff --git a/ansible/roles/gitea-runner/tasks/main.yaml b/ansible/roles/gitea-runner/tasks/main.yaml new file mode 100644 index 0000000..f1adb25 --- /dev/null +++ b/ansible/roles/gitea-runner/tasks/main.yaml @@ -0,0 +1,104 @@ +--- +- name: Download act_runner binary + ansible.builtin.get_url: + url: https://gitea.com/gitea/act_runner/releases/download/v0.2.11/act_runner-0.2.11-linux-amd64 + dest: /usr/local/bin/act_runner + mode: "0755" + become: true + +- name: Create act_runner config directory + ansible.builtin.file: + path: /etc/act_runner + state: directory + mode: "0755" + become: true + +- name: Write act_runner config + ansible.builtin.copy: + dest: /etc/act_runner/config.yaml + content: | + log: + level: info + runner: + fetch_timeout: 5s + fetch_interval: 2s + labels: + - "ubuntu-latest:host" + - "ubuntu-22.04:host" + container: + network: host + privileged: true + valid_volumes: + - "**" + host: + workdir_parent: /tmp/act-runner-work + mode: "0644" + become: true + +- name: Install internal CA certificate + ansible.builtin.copy: + src: /etc/rancher/k3s/homelab-ca.crt + dest: /usr/local/share/ca-certificates/homelab-ca.crt + mode: "0644" + remote_src: true + become: true + +- name: Update CA certificates + ansible.builtin.command: update-ca-certificates + become: true + changed_when: false + +- name: Create act_runner systemd service + ansible.builtin.copy: + dest: /etc/systemd/system/act_runner.service + content: | + [Unit] + Description=Gitea Actions Runner + After=network.target + + [Service] + Environment=GITEA_INSTANCE_URL=https://gitea.home.arpa + Environment=GITEA_RUNNER_REGISTRATION_TOKEN={{ gitea_runner_token }} + Environment=GITEA_RUNNER_NAME=minisforum + Environment=SSL_CERT_FILE=/etc/ssl/certs/homelab-ca.pem + Environment=GIT_SSL_CAINFO=/etc/ssl/certs/homelab-ca.pem + ExecStartPre=/bin/sh -c 'if [ ! -f /etc/act_runner/.runner ]; then cp ~/.runner /etc/act_runner/.runner 2>/dev/null || act_runner register --no-interactive --config /etc/act_runner/config.yaml --instance $GITEA_INSTANCE_URL --token $GITEA_RUNNER_REGISTRATION_TOKEN --name $GITEA_RUNNER_NAME; fi' + ExecStart=/usr/local/bin/act_runner daemon --config /etc/act_runner/config.yaml + WorkingDirectory=/etc/act_runner + Restart=always + RestartSec=5 + + [Install] + WantedBy=multi-user.target + mode: "0644" + become: true + notify: Restart act_runner + +- name: Copy runner registration file if exists + ansible.builtin.shell: | + if [ -f ~/.runner ] && [ ! -f /etc/act_runner/.runner ]; then + cp ~/.runner /etc/act_runner/.runner + fi + become: false + changed_when: false + +- name: Remove docker.sock if it is a directory + ansible.builtin.file: + path: /run/docker.sock + state: absent + become: true + +- name: Enable and start Docker + ansible.builtin.systemd: + name: docker + enabled: true + state: started + become: true + +- name: Enable and start act_runner + ansible.builtin.systemd: + name: act_runner + enabled: true + state: started + daemon_reload: true + become: true \ No newline at end of file diff --git a/manifests/gitea-runner-secret.sh b/manifests/gitea-runner-secret.sh new file mode 100644 index 0000000..6df7c8c --- /dev/null +++ b/manifests/gitea-runner-secret.sh @@ -0,0 +1,13 @@ +#!/bin/bash +# Usage: bash manifests/gitea-runner-secret.sh +# Creates gitea-runner-secret from .env +set -e + +source "$(dirname "$0")/../.env" + +kubectl create secret generic gitea-runner-secret \ + --namespace gitea-runner \ + --from-literal=token="${GITEA_RUNNER_TOKEN}" \ + --dry-run=client -o yaml | kubectl apply -f - + +echo "gitea-runner-secret applied" \ No newline at end of file diff --git a/manifests/gitea-runner.yaml b/manifests/gitea-runner.yaml new file mode 100644 index 0000000..f46365a --- /dev/null +++ b/manifests/gitea-runner.yaml @@ -0,0 +1,105 @@ +# Gitea Actions Runner +# Apply: kubectl apply -f manifests/gitea-runner.yaml +apiVersion: v1 +kind: Namespace +metadata: + name: gitea-runner +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: gitea-runner + namespace: gitea-runner +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gitea-runner + namespace: gitea-runner +spec: + replicas: 1 + selector: + matchLabels: + app: gitea-runner + template: + metadata: + labels: + app: gitea-runner + spec: + serviceAccountName: gitea-runner + nodeSelector: + node-role: primary + containers: + - name: runner + image: gitea/act_runner:latest + env: + - name: GITEA_INSTANCE_URL + value: "https://gitea.home.arpa" + - name: GITEA_RUNNER_REGISTRATION_TOKEN + valueFrom: + secretKeyRef: + name: gitea-runner-secret + key: token + - name: GITEA_RUNNER_NAME + value: "minisforum" + - name: GITEA_RUNNER_LABELS + value: "ubuntu-latest:host,ubuntu-22.04:host" + - name: CONFIG_FILE + value: /config/config.yaml + - name: NODE_EXTRA_CA_CERTS + value: /certs/ca.crt + - name: SSL_CERT_FILE + value: /certs/ca.crt + volumeMounts: + - name: config + mountPath: /config + - name: containerd-sock + mountPath: /var/run/docker.sock + - name: runner-data + mountPath: /data + - name: internal-ca + mountPath: /certs + - name: usr-bin + mountPath: /usr/local/bin/node + subPath: node + dnsConfig: + nameservers: + - 192.168.7.77 + volumes: + - name: config + configMap: + name: gitea-runner-config + - name: containerd-sock + hostPath: + path: /run/k3s/containerd/containerd.sock + - name: runner-data + emptyDir: {} + - name: internal-ca + secret: + secretName: internal-ca-cert + - name: usr-bin + hostPath: + path: /usr/bin/node +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: gitea-runner-config + namespace: gitea-runner +data: + config.yaml: | + log: + level: info + runner: + fetch_timeout: 5s + fetch_interval: 2s + env_vars: + PATH: "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + SSL_CERT_FILE: "/certs/ca.crt" + GIT_SSL_CAINFO: "/certs/ca.crt" + container: + network: host + privileged: true + options: "--add-host=gitea.home.arpa:192.168.7.77" + valid_volumes: + - "**"