Notfallwiederherstellung
Dies ist das Betriebs-Runbook zum Wiederherstellen von Orimora nach einem echten Vorfall. Es ergänzt Backup & Wiederherstellung (was gesichert wird + Zeitplan). Halte eine Kopie dieser Seite — und deinen Recovery-Code — dort bereit, wo du sie erreichst, wenn die Instanz steht.
| Kennzahl | Ziel | Hinweise |
|---|---|---|
| RPO (max. akzeptabler Verlust) | 24 h | Tägliches Backup um 03:00 UTC (BACKUP_SCHEDULE). |
| RTO (max. akzeptable Ausfallzeit) | 4 h | Manuelle Wiederherstellung + Boot; mit diesem Runbook machbar. |
Was du zum Wiederherstellen brauchst
Abschnitt betitelt „Was du zum Wiederherstellen brauchst“- Den aktuellen DB-Dump (
orimora-db-<ts>.dump,pg_dump-Custom-Format). - Das aktuelle Uploads-Archiv (
uploads-<ts>.tar.gz). - Den Recovery-Code — den privaten
age-Schlüssel (AGE-SECRET-KEY-…), der bei der Einrichtung einmalig unter Einstellungen → Admin → Backups angezeigt wird.
Off-Site-Artefakte heißen *.age (verschlüsselt). Lokale Kopien auf dem Host unter BACKUP_PATH sind Klartext (der Host hält ohnehin die Live-DB) — wenn das Host-Volume noch existiert, überspringe den Entschlüsselungsschritt.
Wiederherstellungsablauf (DB + Uploads)
Abschnitt betitelt „Wiederherstellungsablauf (DB + Uploads)“Der PostgreSQL-Client muss zur Major-Version (16) des Servers passen — das Image bringt postgresql16-client mit. age und rclone sind ebenfalls im Image enthalten.
# 0. App stoppen, damit während der Wiederherstellung nichts schreibt.docker compose stop app
# 1. Aktuelle Off-Site-Artefakte holen (Beispiel: rclone-Remote namens "offsite").rclone copy offsite:orimora ./restore --include '*.age'
# 2. Mit dem Recovery-Code entschlüsseln (privater age-Schlüssel).printf '%s\n' "$AGE_SECRET_KEY" > /tmp/orimora-recovery.keyage -d -i /tmp/orimora-recovery.key -o ./restore/db.dump ./restore/orimora-db-<ts>.dump.ageage -d -i /tmp/orimora-recovery.key -o ./restore/uploads.tar.gz ./restore/uploads-<ts>.tar.gz.ageshred -u /tmp/orimora-recovery.key # Schlüssel nicht auf der Platte lassen
# 3. Datenbank wiederherstellen (in eine saubere DB).# Entweder bestehende DB löschen+neu anlegen, oder in eine frische restoren und DATABASE_URL umbiegen.pg_restore --clean --if-exists --no-owner --no-privileges \ --dbname="$DATABASE_URL" ./restore/db.dump
# 4. Uploads wiederherstellen (entpackt zurück nach ./uploads/...).tar -xzf ./restore/uploads.tar.gz -C /app # Ziel an dein Uploads-Elternverzeichnis anpassen
# 5. App starten. Der Entrypoint führt Migrationen fail-closed aus, bevor er ausliefert.docker compose up -d appNach dem Boot prüfen: Login funktioniert, ein Dokument mit Anhang rendert sein Bild (Blob aufgelöst), und Einstellungen → Admin → Backups zeigt grünen Health-Status.
Fehlerszenarien
Abschnitt betitelt „Fehlerszenarien“| Szenario | Was passiert ist | Maßnahme |
|---|---|---|
| (a) Volume-/Host-Verlust | Server oder Platte ist weg. | Neuen Host bereitstellen, Image installieren, Off-Site-*.age ziehen, vollständigen Ablauf fahren. |
| (b) Korrupte DB | DB unlesbar, Host intakt. | Lokalen Klartext-Dump nutzen (Entschlüsselung überspringen); pg_restore --clean in dieselbe DB. |
| (c) Fehlerhafte Migration | Eine Migration hat Schema/Daten zerlegt. | Letzten Pre-Vorfall-Dump wiederherstellen, dann den korrigierten Build deployen. |
| (d) Ransomware / Totalverlust | Host kompromittiert, lokale Backups weg. | Nur aus der Off-Site-Kopie wiederherstellen. Genau dafür sind Off-Site + Verschlüsselung Pflicht. |
Off-Site-Ziele (S3-frei) — rclone-Rezepte
Abschnitt betitelt „Off-Site-Ziele (S3-frei) — rclone-Rezepte“Off-Site nutzt ein rclone-Remote (BACKUP_RCLONE_REMOTE). rclone liest seine Konfiguration aus rclone.conf oder RCLONE_CONFIG_*-Env. Bevorzuge schlüssel-/passwortbasierte Backends (kein OAuth auf einem Headless-Server). Einmal mit rclone config einrichten, dann den Remote-Pfad setzen.
# SFTP zu einer zweiten Maschine (am universellsten — jeder mit einem zweiten Linux-Rechner)[offsite]type = sftphost = backup.example.comuser = orimorakey_file = /home/orimora/.ssh/id_ed25519# → BACKUP_RCLONE_REMOTE=offsite:orimora-backups
# Backblaze B2 (günstiger Objektspeicher, S3-frei, schlüsselbasiert)[offsite]type = b2account = <keyId>key = <applicationKey># → BACKUP_RCLONE_REMOTE=offsite:my-orimora-bucket
# WebDAV (Nextcloud / generisch)[offsite]type = webdavurl = https://cloud.example.com/remote.php/dav/files/orimora/vendor = nextclouduser = orimorapass = <obscured — via `rclone obscure` setzen># → BACKUP_RCLONE_REMOTE=offsite:orimora-backupsFühre mindestens monatlich einen vollständigen Restore-Drill durch, sowie nach jeder Änderung an der Backup-Pipeline. CI fährt bei jedem Push den Round-Trip-Restore und den Encrypt→Off-Site-Round-Trip; der monatliche Drill übt den echten, durchgängigen manuellen Ablauf gegen eine Wegwerf-Umgebung.
Checkliste:
- Off-Site-Artefakte vorhanden und aktuell.
- Mit dem Recovery-Code entschlüsseln.
pg_restorein eine Wegwerf-DB.- Tabellenanzahl stimmt mit der Quelle überein.
- Ein bekanntes Dokument und sein Anhang lösen auf.
- Die Wall-Clock-Zeit festhalten — sie muss ≤ RTO (4 h) liegen.
Siehe auch
Abschnitt betitelt „Siehe auch“- Backup & Wiederherstellung — was gesichert wird, Zeitplan, Verschlüsselungs-Setup
- Konfiguration —
BACKUP_*- und Off-Site-Variablen