diff --git a/CLAUDE.md b/CLAUDE.md index c2a65a8..dec9ef9 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -868,6 +868,7 @@ Automatisches Deployment auf Staging-Server bei Push auf `develop`: - `CLAUDE.md` - Diese Datei (Projekt-Übersicht) - `docs/INFRASTRUCTURE.md` - Server-Architektur & Deployment +- `docs/STAGING-DEPLOYMENT.md` - Staging Deployment Workflow - `docs/anleitungen/TODO.md` - Task-Liste & Roadmap - `docs/anleitungen/SECURITY.md` - Sicherheitsrichtlinien - `scripts/backup/README.md` - Backup-System Dokumentation diff --git a/docs/STAGING-DEPLOYMENT.md b/docs/STAGING-DEPLOYMENT.md new file mode 100644 index 0000000..130cf91 --- /dev/null +++ b/docs/STAGING-DEPLOYMENT.md @@ -0,0 +1,252 @@ +# Staging Deployment + +> **Staging URL:** https://pl.c2sgmbh.de +> **Server:** sv-payload (37.24.237.181) +> **Branch:** `develop` + +--- + +## Übersicht + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ STAGING DEPLOYMENT WORKFLOW │ +│ │ +│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────────────┐│ +│ │ Developer │ │ GitHub │ │ Staging Server ││ +│ │ │ │ Actions │ │ pl.c2sgmbh.de ││ +│ └──────┬───────┘ └──────┬───────┘ └──────────────┬───────────────┘│ +│ │ │ │ │ +│ │ git push │ │ │ +│ │ develop │ │ │ +│ ├───────────────────►│ │ │ +│ │ │ │ │ +│ │ │ 1. Lint Check │ │ +│ │ │ 2. Unit Tests │ │ +│ │ │ ↓ │ │ +│ │ │ [Pre-checks OK?] │ │ +│ │ │ ↓ │ │ +│ │ │ 3. SSH Connect ──────────►│ │ +│ │ │ │ 4. git pull │ +│ │ │ │ 5. pnpm install│ +│ │ │ │ 6. migrate │ +│ │ │ │ 7. build │ +│ │ │ │ 8. pm2 restart │ +│ │ │ │ ↓ │ +│ │ │◄───────────────────────── │ 9. Health Check│ +│ │ │ │ │ +│ │ ✅ Success │ │ │ +│ │◄───────────────────│ │ │ +│ │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +--- + +## Trigger + +| Trigger | Beschreibung | +|---------|--------------| +| **Push auf `develop`** | Automatisches Deployment | +| **workflow_dispatch** | Manuelles Deployment via GitHub UI | + +--- + +## Workflow-Ablauf + +### 1. Pre-deployment Checks (~1 Min) + +```yaml +Jobs: pre-checks +``` + +- ESLint prüfen +- Unit Tests ausführen +- Bei Fehler: Deployment wird abgebrochen + +### 2. Deploy to Staging (~2-3 Min) + +```yaml +Jobs: deploy +``` + +1. SSH-Verbindung zum Server herstellen +2. `git fetch origin develop && git reset --hard origin/develop` +3. `pnpm install --frozen-lockfile` +4. `pnpm payload migrate` +5. `pnpm build` (mit Memory-Limit 2GB) +6. `pm2 restart payload queue-worker` +7. Health Check auf `http://localhost:3000/admin` + +### 3. Verify Deployment + +- HTTP-Status von https://pl.c2sgmbh.de/admin prüfen +- Bei Fehler: Benachrichtigung im Workflow-Summary + +--- + +## Manuelles Deployment + +### Via GitHub UI + +1. Gehe zu: https://github.com/c2s-admin/cms.c2sgmbh/actions +2. Wähle "Deploy to Staging" +3. Klicke "Run workflow" +4. Optional: "Skip tests" aktivieren für schnelleres Deployment + +### Via CLI (auf dem Server) + +```bash +# Vollständiges Deployment +./scripts/deploy-staging.sh + +# Nur Code-Update (ohne Build) +./scripts/deploy-staging.sh --skip-build + +# Ohne Migrationen +./scripts/deploy-staging.sh --skip-migrations + +# Anderer Branch +DEPLOY_BRANCH=feature/xyz ./scripts/deploy-staging.sh +``` + +### Via SSH (Remote) + +```bash +ssh payload@37.24.237.181 'cd ~/payload-cms && ./scripts/deploy-staging.sh' +``` + +--- + +## Konfiguration + +### GitHub Secrets + +| Secret | Beschreibung | +|--------|--------------| +| `STAGING_SSH_KEY` | SSH Private Key für `payload@37.24.237.181` | + +### Environment + +| Variable | Wert | +|----------|------| +| `STAGING_HOST` | 37.24.237.181 | +| `STAGING_USER` | payload | +| `STAGING_PATH` | /home/payload/payload-cms | + +--- + +## Dateien + +| Datei | Beschreibung | +|-------|--------------| +| `.github/workflows/deploy-staging.yml` | GitHub Actions Workflow | +| `scripts/deploy-staging.sh` | Manuelles Deploy-Script | + +--- + +## Logs & Debugging + +### GitHub Actions Logs + +```bash +# Letzte Workflow-Runs anzeigen +gh run list --workflow=deploy-staging.yml + +# Details eines Runs +gh run view + +# Logs eines Jobs +gh run view --job= --log +``` + +### Server Logs + +```bash +# Deployment Log +tail -f /home/payload/logs/deploy-staging.log + +# PM2 Logs +pm2 logs payload --lines 50 +pm2 logs queue-worker --lines 50 +``` + +--- + +## Troubleshooting + +### Build schlägt fehl (OOM) + +```bash +# PM2 stoppen um RAM freizugeben +pm2 stop all + +# Build mit reduziertem Memory +NODE_OPTIONS="--max-old-space-size=1536" pnpm build + +# Services wieder starten +pm2 start ecosystem.config.cjs +``` + +### SSH-Verbindung fehlgeschlagen + +1. Prüfen ob `STAGING_SSH_KEY` Secret korrekt ist +2. Prüfen ob Public Key in `~/.ssh/authorized_keys` auf dem Server ist +3. Prüfen ob Server erreichbar ist: `ping 37.24.237.181` + +### Migrations fehlgeschlagen + +```bash +# Direkt auf dem Server +cd /home/payload/payload-cms +pnpm payload migrate:status +pnpm payload migrate +``` + +### Service startet nicht + +```bash +# PM2 Status prüfen +pm2 status + +# Logs prüfen +pm2 logs payload --err --lines 100 + +# Manuell starten +pm2 start ecosystem.config.cjs +``` + +--- + +## Branching-Strategie + +``` +main (Produktion) + │ + └── develop (Staging) ◄── Feature-Branches + │ + ├── feature/xyz + ├── fix/abc + └── ... +``` + +| Branch | Deployment | URL | +|--------|------------|-----| +| `main` | Produktion (manuell) | cms.c2sgmbh.de | +| `develop` | Staging (automatisch) | pl.c2sgmbh.de | + +--- + +## Workflow-Status prüfen + +```bash +# CLI +gh run list --workflow=deploy-staging.yml --limit=5 + +# Oder im Browser +# https://github.com/c2s-admin/cms.c2sgmbh/actions/workflows/deploy-staging.yml +``` + +--- + +*Letzte Aktualisierung: 14.12.2025* diff --git a/docs/anleitungen/TODO.md b/docs/anleitungen/TODO.md index a99d7cc..a2a2fe4 100644 --- a/docs/anleitungen/TODO.md +++ b/docs/anleitungen/TODO.md @@ -19,7 +19,7 @@ | [ ] | CDN-Integration (Cloudflare) | Caching | | [x] | CI/CD Pipeline erweitern (Lint/Test/Build) | DevOps | | [x] | Staging-Deployment | DevOps | -| [ ] | Memory-Problem lösen (Swap) | Infrastruktur | +| [x] | Memory-Problem lösen (Swap) | Infrastruktur | | [ ] | PM2 Cluster Mode testen | Infrastruktur | ### Niedrige Priorität @@ -105,9 +105,9 @@ ## Build & Infrastructure -- [ ] **Memory-Problem lösen** - - [ ] Swap auf Server aktivieren (2-4GB) - - [ ] Alternativ: Build auf separatem Runner +- [x] **Memory-Problem lösen** *(erledigt: 4GB Swap via ZFS ZVOL auf Proxmox Host)* + - [x] Swap auf Server aktivieren (4GB) + - [x] Container Swap-Limit konfiguriert (`pct set 700 -swap 4096`) - [ ] **PM2 Cluster Mode** - [ ] Multi-Instanz Konfiguration testen diff --git a/scripts/setup-swap-proxmox.sh b/scripts/setup-swap-proxmox.sh new file mode 100755 index 0000000..cf01d6b --- /dev/null +++ b/scripts/setup-swap-proxmox.sh @@ -0,0 +1,94 @@ +#!/bin/bash +# ============================================================================= +# Swap Setup für Proxmox LXC Container +# ============================================================================= +# +# WICHTIG: Dieses Script muss auf dem PROXMOX HOST ausgeführt werden, +# NICHT im LXC Container selbst! +# +# Swap auf ZFS-basierten LXC Containern funktioniert nicht direkt im Container. +# Stattdessen muss Swap auf Host-Ebene konfiguriert werden. +# +# ============================================================================= + +set -e + +echo "==============================================" +echo " Swap Setup für Proxmox LXC Container" +echo "==============================================" +echo "" +echo "WICHTIG: Dieses Script muss auf dem PROXMOX HOST ausgeführt werden!" +echo "" + +# Prüfen ob wir auf dem Host sind +if [ -f /etc/pve/local/qemu-server ] || pveversion &>/dev/null; then + echo "✓ Proxmox Host erkannt" +else + echo "✗ FEHLER: Dieses Script muss auf dem Proxmox Host ausgeführt werden!" + echo "" + echo "Optionen für LXC Container auf ZFS:" + echo "" + echo "Option 1: Swap ZVOL auf Host erstellen (empfohlen)" + echo " Auf dem Proxmox Host ausführen:" + echo " zfs create -V 4G -b 4096 -o compression=zle \\" + echo " -o logbias=throughput -o sync=standard \\" + echo " -o primarycache=metadata -o secondarycache=none \\" + echo " zfs_ssd2/swap" + echo " mkswap /dev/zvol/zfs_ssd2/swap" + echo " swapon /dev/zvol/zfs_ssd2/swap" + echo " echo '/dev/zvol/zfs_ssd2/swap none swap defaults 0 0' >> /etc/fstab" + echo "" + echo "Option 2: Container Memory Limit erhöhen" + echo " In Proxmox GUI oder via CLI:" + echo " pct set 700 -memory 12288 # 12GB RAM" + echo "" + echo "Option 3: Build auf separatem Server" + echo " GitHub Actions Runner für Builds nutzen" + echo "" + exit 1 +fi + +# Für Proxmox Host: ZVOL für Swap erstellen +POOL="zfs_ssd2" +ZVOL_NAME="swap" +ZVOL_SIZE="4G" +ZVOL_PATH="/dev/zvol/${POOL}/${ZVOL_NAME}" + +echo "Erstelle Swap ZVOL: ${POOL}/${ZVOL_NAME} (${ZVOL_SIZE})" + +# Prüfen ob ZVOL bereits existiert +if zfs list "${POOL}/${ZVOL_NAME}" &>/dev/null; then + echo "ZVOL ${POOL}/${ZVOL_NAME} existiert bereits" +else + zfs create -V ${ZVOL_SIZE} -b 4096 \ + -o compression=zle \ + -o logbias=throughput \ + -o sync=standard \ + -o primarycache=metadata \ + -o secondarycache=none \ + "${POOL}/${ZVOL_NAME}" + echo "✓ ZVOL erstellt" +fi + +# Swap formatieren und aktivieren +if ! swapon --show | grep -q "${ZVOL_PATH}"; then + mkswap "${ZVOL_PATH}" + swapon "${ZVOL_PATH}" + echo "✓ Swap aktiviert" +else + echo "Swap bereits aktiv" +fi + +# Zu fstab hinzufügen +if ! grep -q "${ZVOL_PATH}" /etc/fstab; then + echo "${ZVOL_PATH} none swap defaults 0 0" >> /etc/fstab + echo "✓ Zu /etc/fstab hinzugefügt" +else + echo "Bereits in /etc/fstab" +fi + +echo "" +echo "==============================================" +echo " Swap Setup abgeschlossen" +echo "==============================================" +free -h