mirror of
https://github.com/complexcaresolutions/cms.c2sgmbh.git
synced 2026-03-17 19:44:12 +00:00
- Add backup-db.sh for daily automated backups via cron - Add restore-db.sh for interactive database restoration - Add setup-backup.sh for easy setup on new servers - Support local and S3 (Hetzner Object Storage) backup locations - 30-day retention with automatic cleanup - Credentials stored securely in ~/.pgpass and ~/.s3cfg - Comprehensive documentation with disaster recovery checklist 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
303 lines
7.2 KiB
Markdown
303 lines
7.2 KiB
Markdown
# 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
|
|
```
|