# 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: ```yaml 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-latest` → `runs-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.