Backup & Disaster-Recovery¶
Vesana hat ein eingebautes Backup-System unter Admin → Wartung → Backups.
Es ist der eine Standard — kein separater Sidecar, kein manuelles pg_dump nötig.
Vier Arten, ein Katalog¶
Alle Backups landen in EINEM Katalog, an EINEM Ort, unter EINER Aufbewahrungslogik:
| Art | Wann | Umfang |
|---|---|---|
| Geplant | Nach deinen konfigurierten Zeitplänen | wählbar: Voll oder nur Konfiguration |
| Manuell | Knopfdruck „Jetzt sichern" (auch: hochgeladene Backups tragen dieses Label) | wählbar |
| Pre-Restore | Automatisch unmittelbar vor jedem Restore | immer Voll |
| Pre-Update | Automatisch vor jedem GUI-Update | immer nur Konfiguration |
Backups mit reduziertem Umfang tragen in der Liste ein Badge „nur Konfig".
Ein Backup ist ein komprimierter pg_dump (.sql.gz). Ein Voll-Backup enthält den kompletten Dump inklusive TimescaleDB-Hypertables (Check-Historie, Logs). Eine Sicherung nur der Konfiguration lässt die großen operativen Tabellen und Hypertable-Chunks weg — das Schema bleibt erhalten, beim Restore werden diese Tabellen leer angelegt. Größenordnung: ein Voll-Backup kann leicht einige hundert MB umfassen, eine Konfigurations-Sicherung liegt meist im niedrigen einstelligen MB-Bereich.
Backups liegen in einem Docker-Volume, außerhalb des normalen /opt/vesana-Verzeichnisbaums.
FIELD_ENCRYPTION_KEY ist das Einzige, was wirklich nicht ersetzt werden kann
Verschlüsselte DB-Felder (SNMP-Communities, SNMPv3- und SSH-Passwörter) lassen
sich ohne diesen Schlüssel niemals wieder entschlüsseln. Der Schlüssel muss
außerhalb des Backups liegen — im Passwort-Manager + Print-Backup im Tresor.
Backup-Dump und FIELD_ENCRYPTION_KEY getrennt aufbewahren.
Sicheres Aufbewahren¶
Ein Backup-Dump allein reicht nicht als Recovery-Plan, solange der FIELD_ENCRYPTION_KEY fehlt. Praxis-Empfehlung:
- Schlüssel in einem Passwort-Manager hinterlegen (Bitwarden, 1Password, KeePass)
- Zusätzlich offline ausdrucken oder auf einem getrennten Medium ablegen
- Nicht im selben Volume oder derselben Off-Site-Kopie wie die Datenbank-Backups speichern — sonst ist bei Verlust des einen auch das andere weg
Zeitpläne & Aufbewahrung¶
Unter Admin → Wartung → Backups → Zeitpläne & Aufbewahrung kannst du mehrere Zeitpläne parallel anlegen — z. B. ein tägliches Konfigurations-Backup plus ein wöchentliches Voll-Backup. Pro Zeitplan wählst du:
| Feld | Bedeutung |
|---|---|
| Aktiv/Pausiert | Toggle |
| Häufigkeit | täglich / wöchentlich / monatlich |
| Umfang | Voll-Backup / Nur Konfiguration |
| Wochentag | nur bei „wöchentlich" |
| Tag des Monats | nur bei „monatlich" |
| Stunde, Minute (UTC) | wann genau |
| Eigene Aufbewahrung | optional — sonst gilt die globale Standard-Aufbewahrung |
Es gibt bewusst kein freies Cron-Feld — nur Dropdowns für Häufigkeit und Uhrzeit. Solange du keinen eigenen Zeitplan anlegst, läuft der Default: täglich 02:00 UTC, nur Konfiguration, globale Aufbewahrung.
Standard-Aufbewahrung¶
Gilt für manuelle, Pre-Restore- und Pre-Update-Backups sowie für Zeitpläne ohne eigene Werte:
| Einstellung | Default | Bedeutung |
|---|---|---|
| Max. Anzahl | 5 | mehr Backups → älteste fliegen |
| Max. Alter (Tage) | 90 | ältere werden gelöscht |
| Max. Disk (GB) | 10 | Gesamt-Cap über alle Backups zusammen; mindestens eines bleibt immer erhalten |
Das strengste der drei Limits gewinnt (Anzahl, Alter, Disk-Cap). Legt ein Zeitplan eigene Grenzen fest, gelten diese für seine Backups; der Rest folgt weiter der globalen Standard-Aufbewahrung. Ein Cleanup-Lauf räumt alle 6 Stunden auf, zusätzlich direkt nach jedem geplanten Backup und auf manuellen Anstoß.
Verschwindet die Datei eines Backup-Eintrags durch das Aufräumen (z. B. weil das Limit gerade griff), zeigt die Liste dafür ehrlich „Datei fehlt" statt eines toten Download-Links.
Off-Site-Kopie (wichtig)¶
Backups liegen lokal auf diesem Server. Bei einem Totalausfall der Maschine sind sie mit weg. Für echte Disaster-Recovery brauchst du eine Off-Site-Kopie:
- In der UI „Herunterladen" auf einem Backup → speichert die
.sql.gzlokal. - Oder per eigenem Script direkt aus dem Docker-Volume wegkopieren:
docker run --rm -v vesana_backup-data:/src -v $(pwd):/dst alpine \
sh -c 'cp /src/*.sql.gz /dst/'
# danach nach S3 / NAS / USB rotieren
Restore (auf laufendem Server)¶
In der UI: bei einem Backup auf „Restore" klicken → Hostname zur Bestätigung eintippen → Identität frisch bestätigen (Passkey, Authenticator-Code oder Passwort) → einspielen. Backups von einem anderen Server lädst du vorher über Hochladen in den Katalog — auch große Voll-Backups.
Der Restore legt die Datenbank frisch an, statt in die laufende hineinzulöschen: Er beendet offene Datenbank-Sitzungen, erstellt die Datenbank neu und fährt die passenden TimescaleDB-Routinen um den Dump, damit alle Zeitreihen-Chunks korrekt zurückkommen. Davor legt Vesana automatisch einen Pre-Restore-Snapshot an; er und das eingespielte Backup bleiben danach im Katalog sichtbar — der Rückweg ist klickbar. Bei einem Konfigurations-Backup warnt der Dialog, dass der Verlauf danach leer ist. Die Backup-Liste zeigt die tatsächliche (gepackte) Dateigröße.
Restore = Wartungsfenster
Der Restore ersetzt die Datenbank und trennt laufende Sitzungen. Alle Änderungen seit dem gewählten Backup gehen verloren. Nicht während des Betriebs leichtfertig auslösen. Backups liegen zudem nur lokal auf diesem Server — für echte Ausfallsicherheit brauchst du eine Off-Site-Kopie (siehe oben).
Disaster-Recovery: frischer Server¶
Ziel: Server crasht → frischer Server → Backup von gestern rein → Stand von gestern zurück, nichts verloren außer dem laufenden Tag.
- Neuen Server mit dem Setup-Script aufsetzen (wie bei einer Erstinstallation). Beim ersten Start laufen die Migrationen → leeres Schema + TimescaleDB-Extension sind da.
-
FIELD_ENCRYPTION_KEYaus der alten.envübernehmen (sonst sind verschlüsselte Felder nach dem Restore unlesbar) — vor dem Restore, denn Container lesen Umgebungsvariablen nur beim Start:cd /opt/vesana nano .env # Zeile FIELD_ENCRYPTION_KEY= auf den ALTEN Wert setzen docker compose -f docker-compose.customer.yml up -d --force-recreateWirksam ist nur die
.env;secrets/field_encryption_keyist eine Kopie, die niemand liest (dort trotzdem mitpflegen, damit beide übereinstimmen). Ebenso den Signatur-Schlüssel für Logins übernehmen, wenn bestehende Sitzungen weitergelten sollen. 3. Als Super-Admin einloggen → Admin → Wartung → Backups. 4. „Backup hochladen" → die.sql.gzdeiner Off-Site-Kopie wählen. Sie erscheint als manuelles Backup im Katalog. 5. Auf dem hochgeladenen Backup „Restore" → Hostname eintippen → 2FA-Bestätigung → einspielen. 6. Verifizieren: Login mit dem Original-Admin, einen Host mit verschlüsseltemsnmp_communityöffnen (Wert muss intakt sein), Check-Historie eines Services prüfen (Hypertable-Chunks müssen da sein).
Erscheint in Schritt 6 ein verschlüsseltes Feld leer/kaputt, war der
FIELD_ENCRYPTION_KEY nicht der richtige.
Vesana sagt es dir selbst
Nach jedem Restore prüft die Instanz stichprobenartig, ob die verschlüsselten
Werte mit dem aktuellen FIELD_ENCRYPTION_KEY lesbar sind — über alle Orte
hinweg, an denen Geheimnisse liegen (Geräte-Zugangsdaten, Zugangsdaten-Sets,
Collector-Communities, Instanz-Einstellungen). Passt der Schlüssel nicht,
steht statt der Erfolgsmeldung eine Warnung mit den betroffenen Bereichen —
und dieselbe Meldung im Diagnose-Log (restore_key_mismatch). Schritt 6
ersetzt das nicht, aber du erfährst es sofort statt Tage später.
Disaster-Drill¶
Restore ohne Test ist Hoffnung, kein Backup. Empfehlung: einmal pro Quartal das Fresh-Server-Runbook auf einer separaten VM durchspielen — inklusive Schritt 6.