11 KiB
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.orgundstaging.rebreak.org -
Step 1: SSH-Key auf
api.trucko.orgerzeugen
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.orgautorisieren
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_HOST→staging.rebreak.org -
HETZNER_USER→root -
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.ymlanpassen
Ä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.ymlanalog 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.orgundstaging.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 3–5 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.jsbereinigen
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_KEYSecret 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