rebreak-monorepo/docs/superpowers/specs/2026-06-18-self-hosted-github-runner-design.md

9.2 KiB

Self-Hosted GitHub Actions Runner für rebreak-monorepo

Datum: 2026-06-18
Status: Genehmigt — bereit für Implementierungsplanung
Autor: Kimi Code (Brainstorming-Session)
Ziel: GitHub-Actions-Buildkosten eliminieren, indem Backend- und Admin-Builds auf den bereits vorhandenen Hetzner-Server api.trucko.org (128.140.47.53) verlagert werden.


1. Zusammenfassung

Derzeit laufen Backend- und Admin-Builds auf kostenpflichtigen GitHub-gehosteten Runnern (ubuntu-latest). Bei einem privaten Repository führt das bei hoher Push-Frequenz zu Kosten von über 200 €/Monat.

Dieses Design schlägt vor, einen self-hosted GitHub Actions Runner auf dem bereits vorhandenen, aktuell ungenutzten Hetzner-Server api.trucko.org (128.140.47.53, 8 GB RAM) zu betreiben. Der Code-Hosting-Aspekt bleibt vollständig auf GitHub; nur die Build- und Deploy-Ausführung wird auf die eigene Infrastruktur verlagert.

Das Runner-Label raynis-builder ist bewusst generisch gewählt, damit später weitere Raynis-Apps (Mutterfirma von ReBreak) denselben Runner nutzen können.


2. Kontext & Ausgangslage

Aktueller Flow

local dev → push to main
                ↓
        GitHub Actions (ubuntu-latest)
                ↓
        Build Backend / Admin
                ↓
        Upload Artifact
                ↓
        Deploy-Job (ubuntu-latest)
                ↓
        SCP + SSH zu staging.rebreak.org
                ↓
        deploy-from-artifact.sh

Bestehende Komponenten (werden wiederverwendet)

  • .github/workflows/deploy-staging.yml
  • .github/workflows/deploy-admin-staging.yml
  • scripts/deploy-from-artifact.sh
  • scripts/deploy-admin-from-artifact.sh
  • ecosystem.config.js auf staging.rebreak.org

Probleme mit dem aktuellen Setup

  • GitHub Actions Minuten kosten bei privatem Repo über 200 €/Monat.
  • Keine Notwendigkeit für die ursprüngliche Entscheidung, Builds auf GitHub laufen zu lassen (Server-OOM auf CX23) — api.trucko.org hat 8 GB RAM.

3. Ziele

  1. Kosten eliminieren: Keine kostenpflichtigen GitHub Actions Minuten mehr für Backend-/Admin-Builds.
  2. Minimaler Änderungsaufwand: Bestehende Workflows und Deploy-Scripts bleiben weitgehend erhalten.
  3. Sicherheit: Self-hosted Runner wird nicht für Pull Requests von Forks genutzt.
  4. Zuverlässigkeit: Concurrency-Group, Health-Check und atomic deploy bleiben erhalten.

4. Nicht-Ziele

  • Kein Wechsel des Code-Hostings (GitHub bleibt).
  • Kein Ersatz für Windows- oder iOS-Builds (diese bleiben bei GitHub Actions oder werden lokal gebaut).
  • Keine Einführung zusätzlicher CI-Tools wie Gitea, GitLab oder Woodpecker.
  • Keine Änderung an der Production-Infrastruktur auf staging.rebreak.org über das Nötige hinaus.

5. Architektur

GitHub Push (main)
        ↓
GitHub Actions Workflow
        ↓
Self-hosted Runner auf api.trucko.org
        ↓
Checkout → pnpm install → pnpm build → tar artifact
        ↓
SCP artifact zu staging.rebreak.org
        ↓
SSH: bash /srv/rebreak/scripts/deploy-from-artifact.sh
        ↓
Atomic swap .output-staging + pm2 restart + health-check

Komponenten

Komponente Ort Verantwortung
GitHub Repository GitHub Cloud Code-Hosting, Workflow-Definitionen
GitHub Actions Runner api.trucko.org Workflow-Ausführung, Build, Deploy-Trigger
Build-Umgebung api.trucko.org pnpm install, pnpm build, Artifact-Erstellung
Production-Server staging.rebreak.org Artifact entpacken, Migrationen, PM2-Restart
Deploy-Script staging.rebreak.org scripts/deploy-from-artifact.sh / deploy-admin-from-artifact.sh

6. Datenfluss (detailliert)

6.1 Backend-Deploy

  1. Push auf main triggert .github/workflows/deploy-staging.yml.
  2. Workflow-Job build läuft auf runs-on: self-hosted (Runner auf api.trucko.org).
  3. Runner checkt Repo mit actions/checkout@v4 aus.
  4. pnpm install --frozen-lockfile wird ausgeführt.
  5. cd backend && pnpm build erzeugt backend/.output.
  6. Artifact wird gepackt: tar czf backend-output.tar.gz -C backend/.output ..
  7. Artifact wird per SCP auf staging.rebreak.org:/srv/rebreak/backend/.output-incoming.tar.gz kopiert.
  8. imap-idle/ wird per SCP synchronisiert.
  9. Runner führt per SSH bash /srv/rebreak/scripts/deploy-from-artifact.sh aus.
  10. Server entpackt Artifact atomisch, führt ggf. Prisma-Migrationen aus und restartet rebreak-staging.
  11. Health-Check gegen https://staging.rebreak.org/api/auth/me prüft Erreichbarkeit.

6.2 Admin-Deploy

  • Analog zu Backend über .github/workflows/deploy-admin-staging.yml.
  • Ziel: staging.rebreak.org:/srv/rebreak/apps/admin/.output-incoming.tar.gz.
  • Script: scripts/deploy-admin-from-artifact.sh.
  • Health-Check: https://admin.staging.rebreak.org/.

7. Sicherheit

Runner-Isolation

  • Der Runner wird als Repository-Level Runner im rebreak-monorepo registriert, damit nur dieses Repo ihn nutzen kann.
  • Der Runner bekommt ein dediziertes Label: raynis-builder.
  • Der Workflow fordert das Label explizit an: runs-on: [self-hosted, raynis-builder].
  • Der Runner reagiert nicht auf Pull-Request-Events — nur auf push zu main und workflow_dispatch.

SSH-Zugriff

  • Ein neuer SSH-Deploy-Key wird auf api.trucko.org erzeugt.
  • Der Public Key wird auf staging.rebreak.org in /root/.ssh/authorized_keys eingetragen.
  • Der Private Key wird als GitHub Secret (z. B. STAGING_DEPLOY_KEY) im Environment staging hinterlegt.

Secrets

  • Keine Secrets im Runner-Image.
  • Alle sensiblen Daten kommen weiterhin aus GitHub Environments oder Infisical (auf staging.rebreak.org).

8. Fehlerbehandlung

Build-Fehler

  • Wenn pnpm build fehlschlägt, bricht der Workflow ab.
  • Es wird nichts auf staging.rebreak.org kopiert.

Deploy-Fehler

  • deploy-from-artifact.sh bricht bei fehlgeschlagenen Prisma-Migrationen ab.
  • Der alte .output-staging-Ordner bleibt durch atomisches mv erhalten.
  • Health-Check muss bestehen, sonst schlägt der Workflow fehl.

Parallelität

  • Concurrency-Group bleibt erhalten:
    concurrency:
      group: deploy-staging
      cancel-in-progress: false
    
  • Parallele Deploys queueen sich, statt sich gegenseitig abzubrechen.

9. Tests in CI

Aktuell laufen keine automatisierten Tests in den Deploy-Workflows. Mit dem eigenen Runner entstehen hierfür keine zusätzlichen Kosten.

Empfohlener optionaler nächster Schritt:

  • Vitest-Unit-Tests vor dem Build-Schritt ausführen.
  • Reihenfolge: install → lint → test → build → deploy.

Dies ist nicht Teil dieses Designs und wird in einem separaten Plan behandelt.


10. Migrationsschritte

  1. Runner auf api.trucko.org installieren

    • Node.js 24.11.1, pnpm 10.23.0, git einrichten.
    • GitHub Actions Runner herunterladen und konfigurieren.
    • Als Service registrieren (./svc.sh install && ./svc.sh start).
    • Label raynis-builder zuweisen.
  2. SSH-Verbindung einrichten

    • Auf api.trucko.org: ssh-keygen -t ed25519 -f ~/.ssh/rebreak-deploy.
    • Public Key auf staging.rebreak.org in /root/.ssh/authorized_keys eintragen.
    • Private Key als GitHub Secret STAGING_DEPLOY_KEY im Environment staging hinterlegen.
  3. Workflows anpassen

    • runs-on: ubuntu-latestruns-on: [self-hosted, raynis-builder].
    • SSH-Setup-Step an neues Secret STAGING_DEPLOY_KEY anpassen.
    • Node-Setup beibehalten (Version 24.11.1).
  4. Test-Deploy durchführen

    • workflow_dispatch auf main auslösen.
    • Logs auf api.trucko.org und staging.rebreak.org prüfen.
    • Health-Check bestätigen.
  5. Alte Pfade abschalten

    • Nach erfolgreichen Test-Deploys können die alten Webhook-basierten Deploys deaktiviert werden.
    • pm2 stop rebreak-webhook && pm2 save auf staging.rebreak.org (nur auf User-Approval).

11. Risiken & Mitigationen

Risiko Wahrscheinlichkeit Auswirkung Mitigation
Runner-Prozess stürzt ab Niedrig Hoch Runner als systemd-Service laufen lassen; GitHub zeigt Runner offline an.
Build auf api.trucko.org zu langsam Mittel Mittel 8 GB RAM + 8 GB Swap einrichten; SSD statt HDD prüfen.
SSH-Verbindung zwischen Servern failt Niedrig Hoch SSH-Key testen; ssh-keyscan im Workflow nutzen.
Runner wird versehentlich für PRs genutzt Niedrig Hoch Trigger auf push: branches: [main] beschränken; kein pull_request.
Windows-/Native-Builds bleiben kostenpflichtig Sicher Niedrig In separatem Schritt evaluieren (nicht Teil dieses Designs).

12. Offene Punkte

  1. Exakte Spezifikation von api.trucko.org bestätigen (CPU, SSD, OS).
  2. Soll der Runner unter einem dedizierten User laufen oder als root?
  3. Sollen bestehende Webhook-Deploys sofort abgeschaltet oder parallel als Fallback laufen?
  4. Sollen Vitest-Tests vor dem Build integriert werden (separater Plan)?

13. Erwartetes Ergebnis

Nach der Umstellung:

  • Backend- und Admin-Builds laufen auf api.trucko.org.
  • GitHub-Actions-Minutenkosten für diese Workflows fallen nahezu auf null.
  • Die Deploy-Mechanik auf staging.rebreak.org bleibt unverändert.
  • Windows-/Native-Builds bleiben bei GitHub Actions oder werden separat betrachtet.