Skip to content

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

MetrikZielAktuell
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>/):

KomponenteMethodeQuelle
Postgres-DBpg_dump -Fc aus dem pg-<slug>-Containercontainer-internes Volume
MinIO-Bucketmc mirror aus dem minio-<slug>-Containercontainer-internes Volume
Synapse-MediaVolume-Tar des synapse-<slug>-Containers/data/media_store
Box-Configtar über /srv/tenants/<slug>/ ohne *-data-Volumeshomeserver.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)

ServerInhaltWo gesichert
api.prilog.chatprilog_crm-DB, Backend-.env, Nginx-Configs, PM2-ProzesslisteHetzner Storage Box prilog-storage-box-1, daily 03:00 UTC
prilog-mail (Stalwart)Mailserver-Volume komplettStorage Box, daily 03:30 UTC
prilog-wisperStateless — 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:

bash
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=2

Bei 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

SzenarioWahrscheinlichkeitGeschützt?
Disk-Failure auf Shared-Hostmittel✅ 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öschungmittel✅ Point-in-Time-Restore aus prilog-backup/-Bucket
DB-Korruption (Software-Bug)niedrig✅ Vorheriger Tagessnapshot verfügbar
Ransomware auf Hostsehr niedrig✅ Off-Host-Backup ist nicht über die Host-Anmeldung erreichbar
Hetzner-Account kompromittiertsehr niedrigteilweise (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