Zum Inhalt

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:

  1. Schlüssel in einem Passwort-Manager hinterlegen (Bitwarden, 1Password, KeePass)
  2. Zusätzlich offline ausdrucken oder auf einem getrennten Medium ablegen
  3. 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.gz lokal.
  • 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.

  1. Neuen Server mit dem Setup-Script aufsetzen (wie bei einer Erstinstallation). Beim ersten Start laufen die Migrationen → leeres Schema + TimescaleDB-Extension sind da.
  2. FIELD_ENCRYPTION_KEY aus 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-recreate
    

    Wirksam ist nur die .env; secrets/field_encryption_key ist 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.gz deiner 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üsseltem snmp_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.

Anschluss

  • Updates — der Updater legt vor jedem Update ein Pre-Update-Backup im selben Katalog an; ohne Auto-Rollback ist dieses Backup die Recovery-Strategie
  • 2FA — Step-Up-Bestätigung beim Restore