Files
idf-ci/docs/runner-setup.md
T

11 KiB

Gitea Actions Runner — Setup

Diese Anleitung beschreibt, wie der Gitea Actions Runner auf einem IDF-Server installiert und registriert wird. Der Runner ist der Dienst, der die Release-Workflows aus diesem Repo ausführt. Ohne laufenden Runner bleiben Tag-Pushes ohne Wirkung — die Runs hängen unendlich in der Queue.

Wichtig: Diese Anleitung ist die verbindliche SSOT für das Runner-Setup. Bei jedem Server-Wechsel wird sie von vorn abgearbeitet — es gibt keine versteckten Artefakte außerhalb von Git, nur die hier beschriebenen Schritte.

Was der Runner ist und was er nicht ist

Der Runner ist ein einzelnes ausführbares Binary (act_runner), das sich beim IDF-Gitea-Server anmeldet und Jobs aus der Queue abarbeitet. Er ist kein WordPress-, PHP- oder Plesk-Tool, sondern ein unabhängiger Dienst, der nebenher läuft. Technisch ist er vergleichbar mit einem Cron-Daemon, der auf Arbeit wartet.

Der Runner baut die Plugin-ZIPs und legt sie als Gitea-Release-Assets ab. Er verteilt nichts an Kunden — das ist Aufgabe des Master-Key-Plugins.

Voraussetzungen in Gitea

Damit der Runner Reusable-Workflows aus idf-ci lesen kann, muss das Repo für ihn erreichbar sein. Der beim Job generierte Token ist nur für das aufrufende Plugin-Repo gültig und kann kein anderes privates Repo klonen.

Daher: ideenfabrik/idf-ci muss auf Sichtbarkeit „Public" (oder „Limited", falls in der Gitea-Version verfügbar) stehen.

  • Public — lesbar für alle, die die Gitea-Instanz erreichen.
  • Limited — lesbar für alle eingeloggten Gitea-User. In neueren Gitea-Versionen verfügbar. Für unseren Fall äquivalent zu Public, weil der Runner eh mit Token angemeldet ist.
  • Private — funktioniert nicht, weil der Job-Token keinen Repo-übergreifenden Lesezugriff hat.

Zusätzlich: Gitea-weite Einstellung REQUIRE_SIGNIN_VIEW muss auf false stehen. Sonst überschreibt sie die per-Repo-Sichtbarkeit und erzwingt Login auch für Public-Repos. Bei Docker-Setups wird die app.ini oft aus Environment-Variablen regeneriert — Änderungen direkt in der Datei gehen beim Container-Neustart verloren. Korrekter Weg: Environment-Variable setzen:

GITEA__service__REQUIRE_SIGNIN_VIEW=false

Je nach Setup in der docker-compose.yml, im systemd-Unit oder in der Plesk-Gitea-Extension. Container neu starten.

Ist das ein Sicherheitsproblem?

Das Risiko ist niedrig, weil das Repo ausschließlich CI-Baustoff enthält:

  • Keine Access-Tokens, API-Keys oder Passwörter (Secrets werden zur Laufzeit injiziert, nie committet)
  • Keine Plugin-Quellcodes, keine Business-Logik, keine Kundendaten
  • Kein Zugriff auf Produktions-Systeme

Öffentlich lesbar sind nur: der Release-Workflow (Bau-Logik), die Doku und das Caller-Template. Standard-CI-Praxis, wie bei vielen Open-Source-Projekten.

Falls der Gitea-Server aus dem Internet erreichbar ist, bedeutet „Public" tatsächlich weltweit lesbar. Ist der Gitea-Server nur intern/VPN-gebunden erreichbar, ist „Public" effektiv identisch mit „intern lesbar". Im Zweifel: Sichtbarkeit auf „Limited" setzen, dann muss man wenigstens angemeldet sein, um zu lesen.

Umstellung der Repo-Sichtbarkeit

  1. Repo öffnen: https://git.ihre-ideenfabrik.de/ideenfabrik/idf-ci
  2. Settings → ganz runterscrollen → „Danger Zone"
  3. Change Visibility → Public (oder Limited, falls verfügbar)
  4. Bestätigen

Einmalige Aktion pro Instanz.

Voraussetzungen auf dem Server

  • Linux (Debian/Ubuntu; der IDF-Plesk-Host reicht)
  • Outbound-HTTPS zu git.ihre-ideenfabrik.de und zu github.com (für standard Gitea-/GitHub-Actions wie actions/checkout)
  • Node.js 20 (LTS) oder neuer — zahlreiche Actions (actions/checkout, viele weitere) sind JavaScript-basiert und benötigen Node zur Ausführung. Installation (Debian/Ubuntu):
    curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash -
    sudo apt install -y nodejs
    
    Prüfen: node --version (mindestens v20.x).
  • Standard-Tools verfügbar: bash, python3, zip, unzip, rsync, curl, jq, git Falls einzelne Tools fehlen: sudo apt install -y python3 zip unzip rsync curl jq git
  • systemd (Standard bei Debian/Ubuntu)
  • Root-Shell-Zugang

Installation

1. Binary herunterladen

Aktuelle stabile Version (beim Schreiben dieser Doku: v0.2.11) von https://gitea.com/gitea/act_runner/releases holen:

sudo mkdir -p /opt/act_runner
cd /opt/act_runner
sudo curl -L -o act_runner \
  https://gitea.com/gitea/act_runner/releases/download/v0.2.11/act_runner-0.2.11-linux-amd64
sudo chmod +x act_runner

Architektur-Variante: bei ARM-Servern linux-arm64 statt linux-amd64 wählen.

2. Konfigurationsdatei erzeugen und Labels eintragen

sudo ./act_runner generate-config | sudo tee config.yaml > /dev/null

Wichtig: act_runner akzeptiert Labels nur aus der Config, nicht als CLI-Flag beim Registrieren. Die Default-Labels zeigen auf Docker-Images, die wir nicht brauchen. Ersetze sie durch Host-Modus-Labels:

sudo nano /opt/act_runner/config.yaml

Im Block runner: den vorhandenen labels:-Block vollständig ersetzen durch:

  labels:
    - "self-hosted:host"
    - "linux:host"
    - "x64:host"

Suffix :host = Jobs laufen direkt auf dem Host, ohne Docker. Damit sparen wir uns Docker als weitere Abhängigkeit. Speichern und verlassen.

Andere Default-Werte in config.yaml können bleiben. Bei Bedarf später anpassen: runner.capacity für parallele Jobs (Default 1 ist für den Anfang ok).

3. Registrierungstoken in Gitea holen

Organisation-scoped Runner (empfohlen, läuft für alle IDF-Repos):

  1. In Gitea einloggen als Admin.
  2. Navigation: Organization ideenfabrik → Settings → ActionsRunners.
  3. Button „Create new Runner".
  4. Registrierungstoken kopieren. Token ist einmalig — für eine zweite Registrierung einen neuen generieren.

Alternativ: Instance-weit unter Site Administration → Actions → Runners (dann verfügbar für alle Organisationen).

4. Runner registrieren

sudo /opt/act_runner/act_runner register \
  --config /opt/act_runner/config.yaml \
  --instance https://git.ihre-ideenfabrik.de \
  --token <TOKEN_AUS_SCHRITT_3> \
  --name idf-plesk-runner \
  --no-interactive

Kein --labels-Flag — die Labels kommen aus der Config (siehe Schritt 2). Falls versehentlich mitgegeben, erscheint die Warnung Labels from command will be ignored, use labels defined in config file.

Nach erfolgreicher Registrierung liegt eine Datei .runner im Arbeitsverzeichnis — die ist der Runner-State, nicht weiterkopieren oder committen.

5. systemd-Service anlegen

sudo tee /etc/systemd/system/act_runner.service > /dev/null <<'EOF'
[Unit]
Description=Gitea Actions Runner (IDF)
After=network.target

[Service]
Type=simple
WorkingDirectory=/opt/act_runner
ExecStart=/opt/act_runner/act_runner daemon --config /opt/act_runner/config.yaml
Restart=always
RestartSec=5
User=root
Group=root

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable act_runner
sudo systemctl start act_runner

6. Verifikation

sudo systemctl status act_runner

Erwartete Zeile: Active: active (running).

In Gitea prüfen:

  1. Organization ideenfabrik → Settings → ActionsRunners.
  2. Der neue Runner taucht mit Status Online auf.
  3. In der Labels-Spalte müssen self-hosted, linux, x64 stehen. Wenn stattdessen ubuntu-latest o. Ä. dort stehen, wurde ohne die Labels aus Schritt 2 registriert → Schritt 2 prüfen und bei Runs-Hängen neu registrieren (siehe Troubleshooting).

7. Pilot-Test

Einen Plugin-Repo mit Caller-Workflow nehmen (z. B. idf-post-prefix), Tag v<X.Y.Z> pushen, unter Actions im Repo prüfen, ob der Run durchläuft. Bei Erfolg entsteht ein Gitea-Release mit ZIP-Asset.

Laufender Betrieb

  • Logs: sudo journalctl -u act_runner -f (tail-folgen) oder journalctl -u act_runner --since '1 hour ago'.
  • Runner-Update: neues act_runner-Binary herunterladen, ersetzen, sudo systemctl restart act_runner.
  • Label-Änderung: Labels in config.yaml anpassen, Service neu starten (sudo systemctl restart act_runner). Der Daemon sendet die aktualisierten Labels beim nächsten Handshake an Gitea.
  • Neu-Registrierung (z. B. nach kaputtem State): sudo rm /opt/act_runner/.runner, neuen Token aus Gitea holen, Schritt 4 erneut ausführen, Service neu starten.
  • Deregistrierung: Runner in Gitea-UI löschen, .runner-Datei auf dem Server entfernen, Service stoppen.

Server-Wechsel — Checkliste

Wenn der IDF-Server gewechselt wird (neuer Plesk-Host o. ä.):

  1. Diese Anleitung auf dem neuen Server von Schritt 1 an durchlaufen.
  2. In Schritt 3 einen neuen Registrierungstoken erzeugen — alte Tokens nicht wiederverwenden.
  3. Optional: den alten Runner in der Gitea-UI deaktivieren, damit er nicht doppelt zieht.
  4. Nach Verifikation (Schritt 6 + 7): alte Server-Installation zurückbauen.

Damit ist das komplette Build-System portabel: die Bauanleitung lebt in diesem Repo (release-plugin.yml), der Runner wird pro Server neu aufgesetzt nach genau dieser Anleitung. Keine versteckten Scripts außerhalb von Git.

Troubleshooting

Warnung Labels from command will be ignored beim Registrieren. Du hast --labels … als CLI-Flag gesetzt, aber act_runner nimmt Labels nur aus der Config. Schritt 2 durchgehen, Labels in config.yaml eintragen. Dann sudo rm /opt/act_runner/.runner, neuen Token holen, Registrierung ohne --labels-Flag erneut ausführen.

Run bricht ab mit Unable to clone … authentication required. Entweder idf-ci steht auf Private, oder Gitea-weit ist REQUIRE_SIGNIN_VIEW = true aktiv. Abschnitt „Voraussetzungen in Gitea" durchgehen. Bei Docker-Setup die Environment-Variable GITEA__service__REQUIRE_SIGNIN_VIEW=false setzen und Container neu starten. Danach den Run über den Re-run-Button in der Gitea-Actions-UI neu starten.

Run bricht ab mit Cannot find: node in PATH. Node.js ist nicht installiert oder nicht im PATH. Abschnitt „Voraussetzungen auf dem Server" durchgehen und Node 20 LTS installieren. Nach sudo apt install -y nodejs läuft der nächste Re-run.

Runs hängen auf queued, Runner steht aber auf Online. Label-Mismatch. Der Workflow schreibt runs-on: self-hosted, der Runner muss dasselbe Label anbieten. In der Gitea-UI die Labels des Runners prüfen — stehen dort nicht self-hosted, linux, x64, liegt es an Schritt 2.

Runner zeigt offline nach systemd-Start. sudo journalctl -u act_runner --since '5 min ago' lesen. Häufige Ursachen: Token abgelaufen, DNS funktioniert nicht, git.ihre-ideenfabrik.de nicht erreichbar.

Pre-Flight-Check im Workflow schlägt fehl mit „Tool nicht gefunden". Das System-Paket fehlt auf dem Host. sudo apt install -y python3 zip unzip rsync curl jq git nachinstallieren.

Release-Anlage schlägt fehl mit 401/403. secrets: inherit im Caller-Workflow prüfen und sicherstellen, dass der Runner vom Repo aus GITEA_TOKEN bzw. github.token bekommt. Alternativ Access-Token als Secret im Repo/Org setzen.