# Backup-System

Automatisches PostgreSQL-Backup mit lokalem Speicher und optionalem S3-Offsite-Backup.

## Schnellstart

```bash
# Auf neuem Server einrichten
cd /home/payload/payload-cms/scripts/backup
./setup-backup.sh
```

Das Setup-Skript führt interaktiv durch:
1. PostgreSQL-Authentifizierung (`.pgpass`)
2. S3-Konfiguration (`.s3cfg`) - optional
3. Installation des Backup-Skripts
4. Einrichtung des Cron-Jobs
5. Test-Backup

## Manuelle Einrichtung

### 1. PostgreSQL-Authentifizierung

```bash
# .pgpass erstellen
echo "10.10.181.101:5432:payload_db:payload:DEIN_PASSWORT" > ~/.pgpass
chmod 600 ~/.pgpass

# Verbindung testen
psql -h 10.10.181.101 -U payload -d payload_db -c "SELECT 1"
```

### 2. S3-Konfiguration (optional)

```bash
# s3cmd installieren
sudo apt install s3cmd

# .s3cfg erstellen
cat > ~/.s3cfg << 'EOF'
[default]
access_key = DEIN_ACCESS_KEY
secret_key = DEIN_SECRET_KEY
host_base = fsn1.your-objectstorage.com
host_bucket = %(bucket)s.fsn1.your-objectstorage.com
use_https = True
signature_v2 = False
EOF
chmod 600 ~/.s3cfg

# Verbindung testen
s3cmd ls
```

### 3. Backup-Skript installieren

```bash
# Verzeichnis erstellen
mkdir -p /home/payload/backups/postgres

# Skript kopieren
cp scripts/backup/backup-db.sh /home/payload/backups/postgres/
chmod +x /home/payload/backups/postgres/backup-db.sh

# Test
/home/payload/backups/postgres/backup-db.sh --verbose
```

### 4. Cron-Job einrichten

```bash
# Crontab bearbeiten
crontab -e

# Zeile hinzufügen (täglich um 03:00 Uhr)
0 3 * * * /home/payload/backups/postgres/backup-db.sh >> /home/payload/logs/backup-cron.log 2>&1
```

## Backup-Skript Optionen

```bash
# Normales Backup (für Cron)
./backup-db.sh

# Mit detaillierter Ausgabe
./backup-db.sh --verbose
```

### Umgebungsvariablen

| Variable | Default | Beschreibung |
|----------|---------|--------------|
| `PGHOST` | 10.10.181.101 | PostgreSQL Host |
| `PGPORT` | 5432 | PostgreSQL Port |
| `PGDATABASE` | payload_db | Datenbank-Name |
| `PGUSER` | payload | Datenbank-User |
| `S3_BACKUP_ENABLED` | true | S3-Upload aktivieren |
| `S3_BUCKET` | c2s | S3-Bucket-Name |
| `S3_PATH` | backups/postgres | Pfad im Bucket |

## Backup-Speicherorte

| Ort | Pfad | Retention |
|-----|------|-----------|
| Lokal | `/home/payload/backups/postgres/` | 30 Tage |
| S3 | `s3://c2s/backups/postgres/` | 30 Tage |

## Log-Dateien

| Datei | Beschreibung |
|-------|--------------|
| `/home/payload/backups/postgres/backup.log` | Detailliertes Backup-Log |
| `/home/payload/logs/backup-cron.log` | Cron-Ausgabe |

Das Backup-Log wird automatisch rotiert (max. 10MB, behält letzte 1000 Zeilen).

## Restore

### Restore-Skript (empfohlen)

Das interaktive Restore-Skript führt sicher durch den Wiederherstellungsprozess:

```bash
# Interaktive Auswahl aus lokalen Backups
./restore-db.sh

# Interaktive Auswahl aus S3-Backups
./restore-db.sh --from-s3

# Direktes Restore aus lokaler Datei
./restore-db.sh /home/payload/backups/postgres/payload_db_2025-12-11_03-00-00.sql.gz

# Direktes Restore aus S3
./restore-db.sh --from-s3 payload_db_2025-12-11_03-00-00.sql.gz

# Backups auflisten
./restore-db.sh --list      # Lokale Backups
./restore-db.sh --list-s3   # S3-Backups
```

**Das Restore-Skript führt automatisch durch:**
1. Prüfung der Datenbankverbindung
2. Auflistung verfügbarer Backups
3. Download von S3 (falls gewählt)
4. Verifizierung der Backup-Integrität
5. Stoppen von Payload CMS und Queue-Worker
6. Durchführung des Restores
7. Verifizierung der wiederhergestellten Daten
8. Neustart der Anwendung

### Manueller Restore-Prozess

Falls das Skript nicht verfügbar ist:

#### Schritt 1: Anwendung stoppen

```bash
pm2 stop payload
pm2 stop queue-worker
```

#### Schritt 2: Backup auswählen

```bash
# Lokale Backups anzeigen
ls -lah /home/payload/backups/postgres/*.sql.gz

# S3-Backups anzeigen
s3cmd ls s3://c2s/backups/postgres/
```

#### Schritt 3: Backup herunterladen (nur bei S3)

```bash
s3cmd get s3://c2s/backups/postgres/payload_db_YYYY-MM-DD_HH-MM-SS.sql.gz /tmp/
```

#### Schritt 4: Backup verifizieren

```bash
# Integrität prüfen
gzip -t /tmp/payload_db_YYYY-MM-DD_HH-MM-SS.sql.gz && echo "OK" || echo "BESCHÄDIGT"

# Inhalt inspizieren (erste 50 Zeilen)
gunzip -c /tmp/payload_db_YYYY-MM-DD_HH-MM-SS.sql.gz | head -50
```

#### Schritt 5: Restore durchführen

```bash
# Aus lokalem Backup
gunzip -c /home/payload/backups/postgres/payload_db_YYYY-MM-DD_HH-MM-SS.sql.gz | \
  psql -h 10.10.181.101 -U payload -d payload_db

# Aus heruntergeladenem S3-Backup
gunzip -c /tmp/payload_db_YYYY-MM-DD_HH-MM-SS.sql.gz | \
  psql -h 10.10.181.101 -U payload -d payload_db
```

#### Schritt 6: Restore verifizieren

```bash
# Tabellen zählen
psql -h 10.10.181.101 -U payload -d payload_db -c \
  "SELECT COUNT(*) as tables FROM information_schema.tables WHERE table_schema = 'public';"

# Zeilen in wichtigen Tabellen prüfen
psql -h 10.10.181.101 -U payload -d payload_db -c \
  "SELECT 'users' as table, COUNT(*) as rows FROM users
   UNION ALL SELECT 'tenants', COUNT(*) FROM tenants
   UNION ALL SELECT 'posts', COUNT(*) FROM posts
   UNION ALL SELECT 'pages', COUNT(*) FROM pages;"
```

#### Schritt 7: Anwendung starten

```bash
pm2 start payload
pm2 start queue-worker
pm2 status
```

#### Schritt 8: Funktionalität testen

1. Admin-Panel öffnen: https://pl.c2sgmbh.de/admin
2. Login testen
3. Stichprobenartig Inhalte prüfen

### Disaster Recovery Checkliste

Bei vollständigem Systemausfall:

```
□ 1. Neuen Server bereitstellen
□ 2. Repository klonen: git clone https://github.com/c2s-admin/cms.c2sgmbh.git
□ 3. Dependencies installieren: pnpm install
□ 4. .env konfigurieren (aus Dokumentation oder Backup)
□ 5. Backup-System einrichten: ./scripts/backup/setup-backup.sh
□ 6. Neuestes Backup von S3 holen: s3cmd ls s3://c2s/backups/postgres/
□ 7. Restore durchführen: ./scripts/backup/restore-db.sh --from-s3
□ 8. Build erstellen: pnpm build
□ 9. Anwendung starten: pm2 start ecosystem.config.cjs
□ 10. DNS/Reverse Proxy konfigurieren
□ 11. SSL-Zertifikate einrichten (Caddy automatisch)
□ 12. Funktionalität testen
```

### Point-in-Time Recovery

Für Recovery zu einem bestimmten Zeitpunkt:

1. Backup VOR dem gewünschten Zeitpunkt identifizieren
2. Restore durchführen
3. Manuelle Nacharbeit für Daten zwischen Backup und Zielzeitpunkt

**Hinweis:** Für echtes Point-in-Time Recovery wäre PostgreSQL WAL-Archivierung erforderlich (nicht implementiert).

## Sicherheit

- **Keine Credentials im Skript**: Passwörter werden aus `~/.pgpass` und `~/.s3cfg` gelesen
- **Berechtigungen**: Beide Dateien müssen `chmod 600` haben
- **Credential-Dateien nicht committen**: `.pgpass` und `.s3cfg` sind in `.gitignore`

## Troubleshooting

### Backup fehlgeschlagen

```bash
# Log prüfen
tail -50 /home/payload/backups/postgres/backup.log

# Datenbankverbindung testen
psql -h 10.10.181.101 -U payload -d payload_db -c "SELECT 1"

# .pgpass Berechtigungen prüfen
ls -la ~/.pgpass  # Muss 600 sein
```

### S3-Upload fehlgeschlagen

```bash
# S3-Verbindung testen
s3cmd ls

# .s3cfg Berechtigungen prüfen
ls -la ~/.s3cfg  # Muss 600 sein

# S3 manuell testen
s3cmd put testfile.txt s3://c2s/test/
```

### Cron läuft nicht

```bash
# Crontab prüfen
crontab -l

# Cron-Log prüfen
tail -50 /home/payload/logs/backup-cron.log

# Cron-Service Status
systemctl status cron
```
