Backup & Disaster Recovery
Wie wir Tenants vor Datenverlust und Total-Ausfällen schützen — Übersicht für Operator. Vertiefung in disaster-recovery-konzept.
Status (2026-05-10)
Tenant-Box-Backup live seit 2026-05-02. Jeder Tenant hat eigenen Container-Stack auf einem Shared-Host (shared-1 49.12.108.38, shared-2 91.99.190.150, …); jede Box wird einzeln gesichert. Restore in <30 s über admin.prilog.chat/backups oder Tenant-Board → ⚡-Button. Cross-Host-Recovery via Tenant-Migration-Pipeline (Restore mit targetHostId).
SLA
| Metrik | Ziel | Aktuell |
|---|---|---|
| RPO (max. Datenverlust) | 24 h | ~24 h (Daily-Backup 03:00 UTC) |
| RTO (Restore-Dauer) | < 25 min | ~30 s reine Restore-Zeit, plus DNS-TTL |
| Backup-Erfolgsrate | > 99 % | Health-Check + Alarm bei > 24 h ohne erfolgreiches Backup |
Was wird gesichert?
Pro Tenant-Box (/srv/tenants/<slug>/):
| Komponente | Methode | Quelle |
|---|---|---|
| Postgres-DB | pg_dump -Fc aus dem pg-<slug>-Container | container-internes Volume |
| MinIO-Bucket | mc mirror aus dem minio-<slug>-Container | container-internes Volume |
| Synapse-Media | Volume-Tar des synapse-<slug>-Containers | /data/media_store |
| Box-Config | tar über /srv/tenants/<slug>/ ohne *-data-Volumes | homeserver.yaml, docker-compose.yml, connectors/, credentials.env |
Die vier Bestandteile werden in einem Tarball gebündelt, mit AES-256-CBC verschlüsselt (per-Tenant-Key via HKDF aus dem Master-Key in der Backend-.env), in Hetzner Object Storage Frankfurt unter prilog-backup/<host-name>/<slug>/<date>/bundle.tar.gz.enc abgelegt — plus eine manifest.json mit SHA-256-Checksum.
Plus pro Shared-Host (klein, separater Cron):
/etc/prilog/host.json+port-registry.json/etc/nginx/prilog-tenants/
Plattform-Komponenten (kein Tenant-Daten)
| Server | Inhalt | Wo gesichert |
|---|---|---|
| api.prilog.chat | prilog_crm-DB, Backend-.env, Nginx-Configs, PM2-Prozessliste | Hetzner Storage Box prilog-storage-box-1, daily 03:00 UTC |
| prilog-mail (Stalwart) | Mailserver-Volume komplett | Storage Box, daily 03:30 UTC |
| prilog-wisper | Stateless — nur Whisper-Modelle, kein Backup nötig | — |
Plattform-DB-Backups landen auf der gleichen Storage Box wie früher; nur die Tenant-Daten haben sich auf die per-Box-Object-Storage-Strategie verschoben.
Wiederherstellung
Standard-Weg: Admin-Portal
admin.prilog.chat → Sidebar → Backups oder Tenant-Board → ⚡-Button auf der Tenant-Karte. Wizard: Datum wählen → Ziel-Host wählen → Restore. Auto-Provision auf neuem Host falls nötig (~10 min) + Restore (~30 s) + DNS-Cutover.
CLI-Pfad ohne Portal:
ssh -i ~/.ssh/prilog lee@api.prilog.chat
cd /var/www/backend-api
npx tsx scripts/restore-tenant.ts --tenant=<slug> --date=2026-05-09 --target-host-id=2Bei einem Disaster-Drill: monatlicher Random-Tenant wird in einer Sandbox restored, SHA-256 verifiziert, Smoke-Test läuft, Sandbox wird wieder gelöscht. Alarmiert wird, sobald > 95 % Erfolgsrate verlassen werden.
Threat-Modell — wovon wir uns retten
| Szenario | Wahrscheinlichkeit | Geschützt? |
|---|---|---|
| Disk-Failure auf Shared-Host | mittel | ✅ Restore auf neuen Host |
| Hetzner-DC-Outage (FSN1 down) | niedrig | ✅ Restore in andere Location (Object Storage in Frankfurt, Hosts in NBG1/HEL1) |
| Versehentliche Tenant-Löschung | mittel | ✅ Point-in-Time-Restore aus prilog-backup/-Bucket |
| DB-Korruption (Software-Bug) | niedrig | ✅ Vorheriger Tagessnapshot verfügbar |
| Ransomware auf Host | sehr niedrig | ✅ Off-Host-Backup ist nicht über die Host-Anmeldung erreichbar |
| Hetzner-Account kompromittiert | sehr niedrig | teilweise (Backup-Bucket separat geschützt, aber gleicher Anbieter) |
Offene Punkte
Aus project_tenant_box_open_items — bei nächster Gelegenheit:
- L2/L3 (monthly/yearly) mit Object-Lock für Ransomware-Resilienz
- Restore-Drill-Cron mit Sandbox-Host als proaktiver Korruption-Detektor
- Multi-Region-Replikation Frankfurt → Helsinki
- Master-Key-Escrow in Hetzner-Vault (heute nur in Backend-
.env)
Vertiefung
- Disaster-Recovery-Konzept (Implementations-Doku) — Architektur in drei Layern, Cron-Snippets, RTO/RPO-Herleitung, Restore-Engine-Code.
- Tenant-in-a-Box (Architektur) — warum jede Schule einen eigenen Container-Stack hat und was das für Backups bedeutet.
- Tenant-Migration (Implementation) — die Pipeline, die der Restore wiederverwendet (Pre-Snapshot vor Cutover).