No description
  • Shell 51.4%
  • Jinja 48.6%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Kevin Heyer d31dbe732e
All checks were successful
/ image (push) Successful in 36m36s
/ lint (push) Successful in 14s
/ publish (push) Successful in 10s
Take over capacity and name host jobs when adopting a runner
New setting forgejo_runner_capacity (empty = one job per CPU, as
before). adopt.sh takes the capacity of the old configuration over –
the adopted iac CI runner went from 2 parallel jobs to one per CPU.
The check before the question now also lists labels with the host
executor and the user their jobs ran as before: after the adoption
they run as runner, so jobs that ran as root need a sudo rule, which
iac does not create.

Tested in dev containers: adopt of a runner like the old CI runner
(user runner, host:host, capacity 2) → capacity 2 kept, drop-in for
host jobs placed, sudoers untouched; adopt check of a runner as root
(community-scripts layout) names the missing root; fresh install
twice: capacity = CPUs, changed=1. lint.sh green.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 16:33:07 +02:00
.forgejo/workflows Add the app forgejo-runner 2026-10-22 13:17:18 +02:00
.vibe Add the app forgejo-runner 2026-10-22 13:17:18 +02:00
docs Adopt runners installed by community-scripts 2026-10-22 13:48:45 +02:00
files Lift the sandbox for jobs on the host executor 2026-10-22 16:25:12 +02:00
handlers Add the app forgejo-runner 2026-10-22 13:17:18 +02:00
tasks Take over capacity and name host jobs when adopting a runner 2026-10-22 16:33:07 +02:00
templates Take over capacity and name host jobs when adopting a runner 2026-10-22 16:33:07 +02:00
tests Add the app forgejo-runner 2026-10-22 13:17:18 +02:00
.clinerules Add the app forgejo-runner 2026-10-22 13:17:18 +02:00
.cursorrules Add the app forgejo-runner 2026-10-22 13:17:18 +02:00
.windsurfrules Add the app forgejo-runner 2026-10-22 13:17:18 +02:00
AGENTS.md Adopt runners installed by community-scripts 2026-10-22 13:48:45 +02:00
CHANGELOG.md Take over capacity and name host jobs when adopting a runner 2026-10-22 16:33:07 +02:00
CLAUDE.md Add the app forgejo-runner 2026-10-22 13:17:18 +02:00
GEMINI.md Add the app forgejo-runner 2026-10-22 13:17:18 +02:00
iac.json Take over capacity and name host jobs when adopting a runner 2026-10-22 16:33:07 +02:00
README.md Take over capacity and name host jobs when adopting a runner 2026-10-22 16:33:07 +02:00

iac-forgejo-runner

Forgejo Runner für Forgejo Actions als LXC oder VM auf Proxmox VE, auf Debian 13. Die Jobs laufen in Docker-Containern. Teil von iac.

Installation (auf der Proxmox-Node)

  1. In Forgejo einen Runner anlegen – je nach Bereich unter Website-Administration, Organisation oder Repository → Einstellungen → Actions → Runner → Neuen Runner erstellen. URL, UUID und Token notieren.
  2. Den Gast anlegen und die drei Werte im Dialog angeben:
bash -c "$(curl -fsSL https://iac.heyer.systems/forgejo-runner/ct.sh)"   # LXC
bash -c "$(curl -fsSL https://iac.heyer.systems/forgejo-runner/vm.sh)"   # VM

Ohne Dialog: IAC_NONINTERACTIVE=1 und var_*-Variablen – am einfachsten mit dem Generator auf https://iac.heyer.systems/apps/forgejo-runner/.

Einstellung Bedeutung
forgejo_runner_url Adresse des Forgejo, z. B. https://git.example.org/
forgejo_runner_uuid UUID des Runners aus Forgejo
forgejo_runner_token Token des Runners (geheim)
forgejo_runner_labels Labels, durch Komma getrennt. Leer = docker:docker://node:22-trixie
forgejo_runner_capacity Wie viele Jobs gleichzeitig laufen. Leer = einer pro CPU des Gasts

Standard: 2 CPU, 2 GiB RAM, 20 GiB Disk (LXC) bzw. 32 GiB (VM). Images der Jobs brauchen schnell Platz – die Disk nach Bedarf größer wählen.

Später anmelden oder ändern: Die Werte in /etc/iac/settings.env eintragen bzw. ändern (forgejo_runner_url=… usw.), dann update. Ohne alle drei Werte läuft nur Docker, der Dienst forgejo-runner bleibt gestoppt.

LXC oder VM? Der LXC ist unprivilegiert mit nesting=1 – Docker und damit jeder Job teilt sich dort den Kernel mit dem Proxmox-Host. Für Jobs aus fremden Repositories (öffentliche Instanz, Pull Requests von außen) die VM nehmen.

Bestehenden Runner übernehmen (im Gast)

Für einen Runner, der mit community-scripts (ct/forgejo-runner.sh) angelegt wurde:

bash -c "$(curl -fsSL https://iac.heyer.systems/forgejo-runner/adopt.sh)"   # -y: ohne Frage
  • Prüfung (ändert nichts): Runner 13.x in /usr/local/bin, Konfiguration /etc/forgejo-runner/config.yaml mit genau einer Verbindung (URL, UUID, Token) und Labels als Liste. Runner 12.x wird abgelehnt – Runner 13 ändert das Verhalten von Workflows, siehe docs/MIGRATION.md.
  • Sicherung: /etc/forgejo-runner, Unit und Binary nach /var/backups/iac/.
  • Übernahme: URL, UUID, Token, Labels und die Zahl paralleler Jobs (capacity) kommen nach /etc/iac/settings.env – der Runner bleibt in Forgejo derselbe, die Workflows behalten ihre Labels (z. B. linux-amd64). Die Jobs laufen danach in Docker statt Podman: podman und podman-docker werden entfernt, ihre Images in /var/lib/containers bleiben (aufräumen: rm -rf /var/lib/containers). Der Runner läuft als User runner statt root; config.yaml (Token im Klartext, für alle lesbar) wird gelöscht. Andere Einstellungen der alten Konfiguration übernimmt iac nicht. Hat der Runner ein host-Label, laufen diese Jobs danach als User runner ohne Sandbox (siehe unten); lief der alte Dienst als root, brauchen sie für root-Rechte eine sudo-Regel – die Prüfung vor der Rückfrage weist darauf hin.
  • Danach: wie eine neue Installation, Update mit update.

Zugang

Kein Web-UI und kein Login: Der Runner erscheint in Forgejo unter Actions → Runner. Verwaltet wird der Gast als root per SSH.

In einem Workflow mit dem Standard-Label:

jobs:
  test:
    runs-on: docker

Aufbau

Runner /usr/local/bin/forgejo-runner aus den Releases auf code.forgejo.org (Prüfsumme geprüft), Dienst forgejo-runner als User runner in einer systemd-Sandbox
Jobs in Containern von docker.io aus Debian, je Job ein eigenes Docker-Netz. Der Docker-Socket wird nicht in die Job-Container gereicht, privilegierte Container gibt es nicht
Gleichzeitige Jobs einer je CPU des Gasts
Konfiguration /etc/forgejo-runner/config.yml (von iac erzeugt, bei jedem update überschrieben – Änderungen über die Einstellungen oben), Token in /etc/forgejo-runner/token
Daten /var/lib/forgejo-runner (Zustand, Cache von actions/cache), Images in /var/lib/docker
Logs journalctl -u forgejo-runner, die Job-Logs in Forgejo

Ports: keine eingehenden. Der Runner verbindet sich selbst mit Forgejo. Nur die Ports 4100 und 4101 (Cache-Server und -Proxy) sind offen, und zwar nur aus den Docker-Netzen des Gasts (/etc/nftables.d/51-forgejo-runner-cache.nft).

Sicherheit: Der User runner ist in der Gruppe docker und damit faktisch root im Gast. Jeder, der Workflows auf diesem Runner starten kann, kann Container mit beliebigem Inhalt starten. Den Runner deshalb nur für vertrauenswürdige Repositories registrieren.

Jobs direkt im Gast (host-Label): Ein Label mit dem Host-Executor (z. B. host:host oder ein Name ohne Schema) lässt Jobs ohne Container im Dienst selbst laufen, als User runner – z. B. für Image-Builds mit /dev/kvm, Loop-Geräten und Mounts. Solange es so ein Label gibt, hebt iac die Sandbox des Dienstes auf (/etc/systemd/system/forgejo-runner.service.d/50-iac-host-jobs.conf), sonst würde sie auch für diese Jobs gelten und z. B. sudo verhindern; ohne so ein Label bleibt sie bestehen. Root-Rechte gibt iac dem User runner nicht – braucht ein Job sudo, legst du die Regel selbst an (z. B. /etc/sudoers.d/forgejo-runner), iac fasst sie nicht an. Solche Jobs nie durch pull_request auslösen lassen: Wer einen Fork-PR öffnet, hätte sonst Code im Gast.

Aufräumen: iac löscht keine Images der Jobs. Bei Platzmangel: docker image prune -a.

Update (im Gast)

update

Installiert die getestete Version des Runners aus iac.json (Renovate hebt sie nach einem grünen CI-Lauf an) und startet den Dienst dann neu; laufende Jobs können dabei abbrechen. docker.io kommt mit dem Debian-Upgrade von update.

Selbsttest (im Gast)

bash /var/lib/iac/src/core/bin/iac-smoke

Prüft: Version des Runners, runner darf Docker benutzen, ein Container startet (aus einem lokal erzeugten Image, ohne Internet), mit Token läuft der Dienst, ohne bleibt er gestoppt.