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

11 KiB
Raw Permalink Blame History

Self-Hosted GitHub Actions Runner Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Betreiben eines self-hosted GitHub Actions Runners auf api.trucko.org (128.140.47.53) mit dem Label raynis-builder, um Backend- und Admin-Builds für das rebreak-monorepo kostenlos auszuführen und weiterhin auf staging.rebreak.org zu deployen.

Architecture: Code-Hosting bleibt auf GitHub. GitHub Actions Workflows werden auf runs-on: [self-hosted, raynis-builder] umgestellt. Der Runner auf api.trucko.org checkt aus, baut das Artifact und kopiert es per SCP auf staging.rebreak.org. Dort übernimmt das bestehende deploy-from-artifact.sh das Entpacken, Migrations-Check und PM2-Restart.

Tech Stack: GitHub Actions, self-hosted Runner, Hetzner VPS, pnpm, Node.js 24.11.1, SSH/SCP, PM2.


File Structure

File / Pfad Verantwortung Aktion
api.trucko.org (Server) Self-hosted Runner + Build-Umgebung Einrichten
staging.rebreak.org (Server) Production/Staging + Deploy-Script SSH-Key hinzufügen
.github/workflows/deploy-staging.yml Backend-Deploy-Workflow Ändern: runs-on + SSH-Secret
.github/workflows/deploy-admin-staging.yml Admin-Deploy-Workflow Ändern: runs-on + SSH-Secret
GitHub Repo → Settings → Environments → staging Secrets/Variables STAGING_DEPLOY_KEY hinzufügen

Task 1: Server api.trucko.org vorbereiten

Files:

  • Ausführen auf: api.trucko.org (per SSH)

  • Step 1: SSH auf Server verbinden

ssh root@128.140.47.53
  • Step 2: System aktualisieren und Basis-Tools installieren
apt-get update && apt-get install -y curl git build-essential
  • Step 3: Node.js 24.11.1 installieren (via nvm)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
source ~/.bashrc
nvm install 24.11.1
nvm use 24.11.1
node -v

Expected output: v24.11.1

  • Step 4: pnpm 10.23.0 installieren
corepack enable
corepack prepare pnpm@10.23.0 --activate
pnpm -v

Expected output: 10.23.0

  • Step 5: Git-Config für den Runner setzen
git config --global user.name "Raynis Builder"
git config --global user.email "builder@raynis.dev"
  • Step 6: Workspace-Verzeichnis anlegen
mkdir -p /srv/raynis-builder
chown root:root /srv/raynis-builder

Task 2: GitHub Actions Runner installieren und registrieren

Files:

  • Ausführen auf: api.trucko.org

  • Zu prüfen in GitHub: Settings → Actions → Runners

  • Step 1: Runner-Version ermitteln (aktuellste)

RUNNER_VERSION=$(curl -sL https://api.github.com/repos/actions/runner/releases/latest | jq -r '.tag_name' | sed 's/^v//')
echo "$RUNNER_VERSION"
  • Step 2: Runner herunterladen und entpacken
cd /srv/raynis-builder
curl -o actions-runner-linux-x64-${RUNNER_VERSION}.tar.gz -L https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-linux-x64-${RUNNER_VERSION}.tar.gz
tar xzf actions-runner-linux-x64-${RUNNER_VERSION}.tar.gz
rm actions-runner-linux-x64-${RUNNER_VERSION}.tar.gz
  • Step 3: Runner konfigurieren (Token aus GitHub holen)

In GitHub: Repository rebreak-monorepo → Settings → Actions → Runners → New self-hosted runner → Linux → x64.

Dort angezeigte config.sh-Befehle auf dem Server ausführen, z. B.:

cd /srv/raynis-builder
./config.sh --url https://github.com/RaynisDev/rebreak --token <TOKEN_AUS_GITHUB> --name raynis-builder-01 --labels raynis-builder --work _work
  • Step 4: Runner als systemd-Service registrieren
cd /srv/raynis-builder
./svc.sh install
./svc.sh start
./svc.sh status

Expected: active (running)

  • Step 5: Runner in GitHub UI als Online verifizieren

In GitHub: Settings → Actions → Runners → Status muss Idle oder Online zeigen.


Task 3: SSH-Deploy-Key zwischen Servern einrichten

Files:

  • Ausführen auf: api.trucko.org und staging.rebreak.org

  • Step 1: SSH-Key auf api.trucko.org erzeugen

ssh-keygen -t ed25519 -f /root/.ssh/rebreak-deploy -C "raynis-builder@api.trucko.org" -N ""
cat /root/.ssh/rebreak-deploy.pub
  • Step 2: Public Key auf staging.rebreak.org autorisieren
ssh root@staging.rebreak.org
mkdir -p /root/.ssh
cat >> /root/.ssh/authorized_keys << 'EOF'
<PUBLIC_KEY_VON_OBEN>
EOF
chmod 600 /root/.ssh/authorized_keys
  • Step 3: Verbindung vom Builder zum Staging testen
ssh -i /root/.ssh/rebreak-deploy root@staging.rebreak.org "whoami"

Expected output: root

  • Step 4: SSH-Konfiguration für einfacheren Zugriff anlegen

Auf api.trucko.org:

cat >> /root/.ssh/config << 'EOF'
Host rebreak-staging
    HostName staging.rebreak.org
    User root
    IdentityFile ~/.ssh/rebreak-deploy
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null
EOF
chmod 600 /root/.ssh/config
  • Step 5: Verbindung mit Alias testen
ssh rebreak-staging "whoami"

Expected output: root


Task 4: GitHub Secrets aktualisieren

Files:

  • GitHub Repository: Settings → Environments → staging

  • Step 1: Neuen Private Key als Secret hinzufügen

Auf api.trucko.org:

cat /root/.ssh/rebreak-deploy

Inhalt kopieren und in GitHub einfügen:

  • Environment: staging

  • Secret-Name: STAGING_DEPLOY_KEY

  • Wert: Inhalt von /root/.ssh/rebreak-deploy

  • Step 2: Bestehende Secrets überprüfen

In GitHub prüfen, dass folgende Secrets/Vars im Environment staging vorhanden sind:

  • HETZNER_SSH_KEY → kann später entfernt werden, wenn neuer Key funktioniert

  • HETZNER_HOSTstaging.rebreak.org

  • HETZNER_USERroot

  • Step 3: Altes Secret nicht löschen (Fallback)

HETZNER_SSH_KEY erst nach erfolgreichem Test-Deploy entfernen.


Task 5: Workflows auf self-hosted Runner umstellen

Files:

  • Modify: .github/workflows/deploy-staging.yml

  • Modify: .github/workflows/deploy-admin-staging.yml

  • Step 1: deploy-staging.yml anpassen

Ändere in beiden Jobs runs-on: ubuntu-latest zu:

runs-on: [self-hosted, raynis-builder]

Ändere den SSH-Setup-Step, sodass er STAGING_DEPLOY_KEY verwendet:

      - name: Setup SSH
        env:
          SSH_PRIVATE_KEY: ${{ secrets.STAGING_DEPLOY_KEY }}
          SSH_HOST: ${{ vars.HETZNER_HOST }}
        run: |
          if [ -z "$SSH_PRIVATE_KEY" ] || [ -z "$SSH_HOST" ]; then
            echo "FATAL: STAGING_DEPLOY_KEY oder HETZNER_HOST nicht gesetzt"
            exit 1
          fi
          mkdir -p ~/.ssh
          printf '%s\n' "$SSH_PRIVATE_KEY" > ~/.ssh/id_ed25519
          chmod 600 ~/.ssh/id_ed25519
          ssh-keyscan -H "$SSH_HOST" >> ~/.ssh/known_hosts
  • Step 2: deploy-admin-staging.yml analog anpassen

Gleiche Änderungen wie bei deploy-staging.yml:

runs-on: [self-hosted, raynis-builder]

und SSH-Setup-Step auf STAGING_DEPLOY_KEY umstellen.

  • Step 3: Node-Setup überprüfen

Da der Runner Node.js 24.11.1 und pnpm 10.23.0 bereits hat, kann der Schritt actions/setup-node theoretisch entfallen. Für Robustheit aber beibehalten:

      - uses: actions/setup-node@v4
        with:
          node-version: 24.11.1
          cache: pnpm

Hinweis: cache: pnpm funktioniert auf self-hosted Runnern nur, wenn der Runner persistent ist. Da der Server nicht bei jedem Job neu aufgesetzt wird, ist das gegeben.

  • Step 4: Beide Dateien lokal validieren
cd /Users/chahinebrini/mono/rebreak-monorepo
git diff .github/workflows/deploy-staging.yml .github/workflows/deploy-admin-staging.yml
  • Step 5: Änderungen commiten
git add .github/workflows/deploy-staging.yml .github/workflows/deploy-admin-staging.yml
git commit -m "ci: use self-hosted runner raynis-builder on api.trucko.org"

Task 6: Test-Deploy durchführen

Files:

  • GitHub Actions UI

  • Server-Logs auf api.trucko.org und staging.rebreak.org

  • Step 1: Workflow manuell triggern

In GitHub: Actions → Deploy Staging → Run workflow → Branch: main → Run.

  • Step 2: Build-Logs auf Runner verfolgen

Auf api.trucko.org:

tail -f /srv/raynis-builder/_diag/Worker_*.log
tail -f /srv/raynis-builder/_diag/SelfUpdate-*.log
  • Step 3: Deploy-Logs auf Staging verfolgen

Auf staging.rebreak.org:

pm2 logs rebreak-staging --lines 50
  • Step 4: Health-Check manuell ausführen

Lokal oder auf api.trucko.org:

for i in $(seq 1 12); do
  STATUS=$(curl -sS -o /dev/null -w '%{http_code}' https://staging.rebreak.org/api/auth/me 2>/dev/null || echo "000")
  echo "Attempt $i: $STATUS"
  [ "$STATUS" = "401" ] || [ "$STATUS" = "200" ] && echo "PASSED" && break
  sleep 5
done

Expected: PASSED

  • Step 5: Admin-Deploy testen

In GitHub: Actions → Deploy Admin Staging → Run workflow.

Health-Check:

curl -sS -o /dev/null -w '%{http_code}' https://admin.staging.rebreak.org/

Expected: Nicht 000, 502 oder 503.


Task 7: Alten Webhook-Deploy abschalten (optional, nach stabilem Betrieb)

Files:

  • Ausführen auf: staging.rebreak.org

  • GitHub Repo: Settings → Webhooks

  • Step 1: Mindestens 35 erfolgreiche Deploys über neuen Runner abwarten

  • Step 2: GitHub-Webhook deaktivieren

In GitHub: Settings → Webhooks → https://staging.rebreak.org/webhook → Active: aus.

  • Step 3: Webhook-Service auf Server stoppen
ssh root@staging.rebreak.org
pm2 stop rebreak-webhook
pm2 save
  • Step 4: Legacy-Dateien archivieren (nicht löschen)
cd /srv/rebreak
mkdir -p scripts/legacy
mv scripts/deploy.sh scripts/legacy/deploy.sh
mv scripts/deploy-webhook scripts/legacy/deploy-webhook
  • Step 5: ecosystem.config.js bereinigen

Entferne den Block für rebreak-webhook aus ecosystem.config.js und deploye die Änderung.


Task 8: Cleanup und Monitoring

  • Step 1: Altes HETZNER_SSH_KEY Secret aus GitHub entfernen

Nur nachdem STAGING_DEPLOY_KEY erfolgreich getestet wurde.

  • Step 2: Runner-Verfügbarkeit überwachen

In GitHub: Settings → Actions → Runners → Status regelmäßig prüfen.

  • Step 3: Log-Rotation auf Runner einrichten
logrotate --version || apt-get install -y logrotate
cat > /etc/logrotate.d/github-runner << 'EOF'
/srv/raynis-builder/_diag/*.log {
    daily
    rotate 7
    compress
    missingok
    notifempty
}
EOF
  • Step 4: pnpm-Store auf Runner bereinigen (monatlich)
pnpm store prune

Self-Review

Spec coverage

  • Self-hosted Runner auf api.trucko.org: Task 1 + 2
  • Label raynis-builder: Task 2
  • Code-Hosting bleibt auf GitHub: implizit durch GitHub Actions
  • Workflows auf runs-on: [self-hosted, raynis-builder]: Task 5
  • Deploy zu staging.rebreak.org: Task 3 + 4 + 6
  • Sicherheit (kein PR-Trigger): Task 5 (Workflow-Trigger bleibt push: branches: [main])
  • Webhook abschalten: Task 7

Placeholder scan

Keine TBD/TODO. Alle Befehle sind konkret.

Konsistenz

  • Label durchgehend raynis-builder
  • Secret-Name durchgehend STAGING_DEPLOY_KEY
  • Node-Version durchgehend 24.11.1
  • pnpm-Version durchgehend 10.23.0
  • Server-IP durchgehend 128.140.47.53