Inhalt
  1. Übersicht
  2. Backup-Strategie
  3. Backup-Verifizierung
  4. Wiederherstellung (Docker Compose)
  5. Wiederherstellung (Kubernetes)
  6. Komponenten-Recovery-Matrix
  7. Failover-Checkliste
  8. Datenverlust-Szenarien
  9. DR-Tests

Übersicht

Dieses Runbook beschreibt die Backup-, Wiederherstellungs- und Disaster-Recovery-Verfahren für Reva. Es gilt sowohl für Docker-Compose- als auch für Kubernetes-Deployments (k3s).

PostgreSQL ist die einzige zustandsbehaftete Komponente. Alle anderen Dienste (Redis, Ollama, MCP-Server, die Reva-Anwendung selbst) sind zustandslos und starten nach einem Neustart automatisch.

Wiederherstellungsziele

MetrikZielwertBegründung
RPO (Recovery Point Objective)24 StundenTäglicher Backup-Zeitplan
RTO (Recovery Time Objective)30 MinutenWiederherstellung + Neustart + Verifizierung

Das RPO von 24 Stunden spiegelt den standardmäßigen täglichen Backup-Zeitplan wider. Für strengere RPO-Anforderungen erhöhen Sie die Backup-Frequenz durch Anpassung des Cron-Zeitplans oder CronJob-Intervalls.

Backup-Strategie

Automatische tägliche Backups per Cron auf dem Produktionsserver:

0 2 * * * /home/evdb/roberta/bin/backup-db.sh

Das Skript (bin/backup-db.sh) führt pg_dump im reva-postgres-Container aus, komprimiert mit gzip und speichert das Ergebnis im Verzeichnis backups/. Backups älter als 30 Tage werden automatisch gelöscht.

Manuelles Backup:

./bin/backup-db.sh

Backup-Dateien werden als reva_YYYY-MM-DD_HHMMSS.sql.gz im Verzeichnis backups/ gespeichert.

Ein CronJob (k8s/db-backup-cronjob.yaml) läuft täglich um 02:00 UTC. Er verwendet das pgvector/pgvector:pg16-Image, um pg_dump gegen den postgres-Service auszuführen, komprimiert mit gzip und schreibt auf das db-backups-PVC (5Gi, local-path Storage Class). Backups älter als 30 Tage werden automatisch bereinigt.

Manuelles Backup auslösen:

kubectl create job --from=cronjob/db-backup db-backup-manual -n reva
kubectl logs -n reva job/db-backup-manual -f

Aufbewahrungsrichtlinie

UmgebungSpeicherortAufbewahrungMax. Speicher
Docker Composebackups/ auf dem Host-Dateisystem30 TageUnbegrenzt (Host-Festplatte)
KubernetesPVC db-backups30 Tage5Gi

Backup-Verifizierung

Verfügbare Backups auflisten

ls -lht backups/reva_*.sql.gz
kubectl run backup-ls --rm -it --restart=Never -n reva \
  --image=pgvector/pgvector:pg16 \
  --overrides='{
    "spec": {
      "containers": [{
        "name": "backup-ls",
        "image": "pgvector/pgvector:pg16",
        "command": ["ls", "-lht", "/backups/"],
        "volumeMounts": [{"name": "backups", "mountPath": "/backups"}]
      }],
      "volumes": [{
        "name": "backups",
        "persistentVolumeClaim": {"claimName": "db-backups"}
      }]
    }
  }'

Testwiederherstellung in temporärer Datenbank

Hiermit wird überprüft, ob eine Backup-Datei wiederherstellbar ist, ohne die Produktionsdatenbank zu berühren.

# Backup zur Verifizierung auswählen
BACKUP_FILE="backups/reva_2026-03-15_020000.sql.gz"

# Temporäre Datenbank erstellen, wiederherstellen, dann löschen
docker exec reva-postgres psql -U postgres -c "CREATE DATABASE reva_dr_test;"
gunzip -c "$BACKUP_FILE" | docker exec -i reva-postgres psql -U postgres -d reva_dr_test
docker exec reva-postgres psql -U postgres -d reva_dr_test \
  -c "SELECT count(*) FROM reva_subscriptions;"
docker exec reva-postgres psql -U postgres -c "DROP DATABASE reva_dr_test;"

Wenn das SELECT fehlerfrei eine Zeilenanzahl zurückgibt, ist das Backup gültig. Führen Sie diese Prüfung regelmäßig durch, um die Wiederherstellbarkeit Ihrer Backups sicherzustellen.

Wiederherstellung (Docker Compose)

Voraussetzungen

Schritt für Schritt

# 1. Backup zur Wiederherstellung auswählen
BACKUP_FILE="backups/reva_2026-03-15_020000.sql.gz"

# 2. Anwendung stoppen (Datenbank weiterlaufen lassen)
docker compose stop reva

# 3. Aktive Datenbankverbindungen beenden
docker exec reva-postgres psql -U postgres -c \
  "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'reva' AND pid <> pg_backend_pid();"

# 4. Backup wiederherstellen (--clean --if-exists im Dump behandelt DROP/CREATE)
gunzip -c "$BACKUP_FILE" | docker exec -i reva-postgres psql -U postgres -d reva

# 5. Anwendung neustarten
docker compose up -d reva

# 6. Auf Start warten und Health prüfen
sleep 10
curl -s http://localhost:3978/api/health | python3 -m json.tool

Erwartete Health-Antwort

{
  "status": "ok",
  "adapter_initialized": true,
  "db": true,
  "mcp": {
    "release": {"connected": true},
    "jira": {"connected": true}
  }
}

Falls "db": false: Prüfen Sie sofort die PostgreSQL-Logs mit docker compose logs postgres. Häufige Ursachen sind beschädigte Dump-Dateien oder unzureichender Speicherplatz.

Wiederherstellung (Kubernetes)

Voraussetzungen

Schritt für Schritt

# 1. Anwendung herunterskalieren, um DB-Verbindungen zu beenden
kubectl scale deployment reva -n reva --replicas=0

# 2. Backup zur Wiederherstellung identifizieren
kubectl run backup-ls --rm -it --restart=Never -n reva \
  --image=pgvector/pgvector:pg16 \
  --overrides='{
    "spec": {
      "containers": [{
        "name": "backup-ls",
        "image": "pgvector/pgvector:pg16",
        "command": ["ls", "-lht", "/backups/"],
        "volumeMounts": [{"name": "backups", "mountPath": "/backups"}]
      }],
      "volumes": [{
        "name": "backups",
        "persistentVolumeClaim": {"claimName": "db-backups"}
      }]
    }
  }'

# 3. Aus Backup wiederherstellen (Dateinamen bei Bedarf anpassen)
BACKUP_NAME="reva_2026-03-15_020000.sql.gz"

kubectl run db-restore --rm -it --restart=Never -n reva \
  --image=pgvector/pgvector:pg16 \
  --overrides='{
    "spec": {
      "containers": [{
        "name": "db-restore",
        "image": "pgvector/pgvector:pg16",
        "command": ["sh", "-c", "gunzip -c /backups/'"$BACKUP_NAME"' | PGPASSWORD=$POSTGRES_PASSWORD psql -h postgres -U postgres -d reva"],
        "env": [{"name": "POSTGRES_PASSWORD", "valueFrom": {"secretKeyRef": {"name": "reva-postgres-admin-password", "key": "password"}}}],
        "volumeMounts": [{"name": "backups", "mountPath": "/backups"}]
      }],
      "volumes": [{
        "name": "backups",
        "persistentVolumeClaim": {"claimName": "db-backups"}
      }]
    }
  }'

# 4. Anwendung wieder hochskalieren
kubectl scale deployment reva -n reva --replicas=1

# 5. Auf Rollout warten und Health prüfen
kubectl rollout status deployment/reva -n reva --timeout=120s
kubectl exec -n reva deployment/reva -- curl -s http://localhost:3978/api/health

Schritt 1 nicht überspringen. Das Herunterskalieren der Anwendung stellt sicher, dass keine aktiven Verbindungen die Wiederherstellung stören. Eine Wiederherstellung bei laufender App kann zu inkonsistentem Zustand führen.

Komponenten-Recovery-Matrix

Diese Matrix ermöglicht eine schnelle Bestimmung der Recovery-Maßnahmen pro Komponente während eines Vorfalls.

KomponenteZustandsbehaftet?Wiederherstellung nötig?Recovery-Maßnahme
PostgreSQLJaJaAus Backup wiederherstellen (siehe Abschnitte 4/5)
RedisNein (flüchtiger Cache)NeinStartet leer; App baut Cache bei Bedarf neu auf
OllamaNein (Modelle auf Festplatte)NeinModelle werden bei Bedarf automatisch neu heruntergeladen (ollama pull)
MCP-Server (Release, Jira)NeinNeinZustandslose Container; verbinden sich beim Neustart neu
Reva-AnwendungNeinNeinZustandslose FastAPI-App; Tabellen werden automatisch via metadata.create_all() erstellt

Nur PostgreSQL erfordert aktives Backup und Wiederherstellung. Alle anderen Komponenten sind entweder zustandslos oder speichern Daten, die automatisch regeneriert werden können.

Failover-Checkliste

Kurzreferenz-Checkliste für die Incident Response:

  1. Bewerten — Identifizieren, welche Komponente ausgefallen ist (curl /api/health, docker compose ps oder kubectl get pods -n reva)
  2. Kommunizieren — Stakeholder benachrichtigen, dass der Bot vorübergehend nicht verfügbar ist
  3. PostgreSQL prüfen — Falls DB ausgefallen, Logs prüfen (docker compose logs postgres / kubectl logs -n reva statefulset/postgres)
  4. Aktuelles Backup prüfen — Sicherstellen, dass das neueste Backup existiert und nicht leer ist (siehe Backup-Verifizierung)
  5. Bei Bedarf wiederherstellen — Wiederherstellungsverfahren für Ihre Umgebung befolgen (Docker Compose oder Kubernetes)
  6. Health verifizierencurl /api/health muss "status": "ok" mit "db": true zurückgeben
  7. MCP-Konnektivität verifizieren — Health-Antwort sollte "connected": true für Release und Jira zeigen
  8. Bot testen — Testnachricht in Teams senden, um End-to-End-Funktionalität zu bestätigen
  9. Post-mortem — Ursache, Zeitverlauf und Folgemaßnahmen dokumentieren

Zeit ist entscheidend. Arbeiten Sie diese Checkliste sequenziell ab. Überspringen Sie nicht den Kommunikationsschritt — Stakeholder sollten informiert sein, bevor Sie mit der Wiederherstellung beginnen.

Datenverlust-Szenarien

Datenbank beschädigt oder verloren

Auswirkung: Alle Gesprächsverläufe, Benutzer-Erinnerungen, Benachrichtigungs-Abonnements und Aktivitätsprotokolle gehen verloren.

Wiederherstellung: Aus dem neuesten Backup wiederherstellen. Maximaler Datenverlust = 24 Stunden (RPO). Die Reva-Anwendung erstellt Tabellen beim Start automatisch, wenn sie fehlen — d.h. auch ohne Backup startet der Service, jedoch ohne historische Daten.

# Docker Compose: vollständige Datenbank-Neuerstellung
docker compose down postgres
docker volume rm reva_postgres-data   # Beschädigtes Volume entfernen
docker compose up -d postgres         # Neue PostgreSQL-Instanz
# Warten, bis Postgres bereit ist, dann wiederherstellen:
sleep 5
gunzip -c backups/reva_LATEST.sql.gz | docker exec -i reva-postgres psql -U postgres -d reva
docker compose up -d reva

Kein Backup verfügbar

Auswirkung: Vollständiger Datenverlust. Historische Gespräche und Erinnerungen können nicht wiederhergestellt werden.

Wiederherstellung: Neu starten. Die Anwendung erstellt alle erforderlichen Tabellen beim Start. Benutzer müssen Benachrichtigungen neu abonnieren. Externe Systeme (Release, Jira) sind nicht betroffen, da sie die Datenquelle für Release-/Issue-Daten sind.

docker compose down
docker volume rm reva_postgres-data
docker compose up -d
kubectl delete pvc postgres-data -n reva
kubectl rollout restart statefulset/postgres -n reva
kubectl rollout restart deployment/reva -n reva

Redis verloren oder beschädigt

Auswirkung: Minimal. Redis wird als flüchtiger Cache verwendet. Es tritt kein Datenverlust auf.

docker compose restart redis
kubectl rollout restart deployment/redis -n reva

MCP-Server nicht erreichbar

Auswirkung: Bot kann nicht mit Digital.ai Release oder Jira interagieren. Gespräche und Erinnerungen funktionieren weiterhin.

Wiederherstellung: MCP-Server verbinden sich automatisch wieder, sobald der Upstream-Dienst verfügbar ist. Netzwerkverbindung und Upstream-Service-Health prüfen.

# MCP-Status prüfen
curl -s http://localhost:3978/api/health | python3 -c \
  "import sys,json; d=json.load(sys.stdin); print(json.dumps(d.get('mcp',{}), indent=2))"
docker compose restart release-mcp jira-mcp
# MCP-Sidecars sind Teil des Reva-Pods
kubectl rollout restart deployment/reva -n reva

Ollama nicht verfügbar

Auswirkung: Bot kann keine Nachrichten verarbeiten (LLM-Inferenz offline). Kein Datenverlust.

Wiederherstellung: Ollama neustarten. Modelle sind auf der Festplatte gespeichert und bleiben über Neustarts erhalten. Falls die Modelldateien verloren gehen, werden sie bei der ersten Verwendung automatisch neu heruntergeladen.

docker compose restart ollama
sudo systemctl restart ollama

# Modellverfügbarkeit prüfen
curl -s http://localhost:11434/api/tags | python3 -c \
  "import sys,json; [print(m['name']) for m in json.load(sys.stdin)['models']]"

DR-Tests

Zeitplan

Führen Sie vierterljährlich einen vollständigen DR-Test durch. Dokumentieren Sie die Ergebnisse im Incident-Log des Teams.

Testverfahren

  1. Test-Backup erstellen von der aktuellen Produktionsdatenbank.
  2. In separater Umgebung wiederherstellen (nicht auf Produktion testen).
    # Testdatenbank neben Produktion erstellen
    docker exec reva-postgres psql -U postgres -c "CREATE DATABASE reva_dr_test;"
    gunzip -c backups/reva_LATEST.sql.gz | docker exec -i reva-postgres psql -U postgres -d reva_dr_test
  3. Datenintegrität prüfen:
    # Tabellenexistenz und Zeilenzahlen prüfen
    docker exec reva-postgres psql -U postgres -d reva_dr_test -c "\dt"
    docker exec reva-postgres psql -U postgres -d reva_dr_test -c "
      SELECT 'conversations' AS tbl, count(*) FROM conversations
      UNION ALL SELECT 'memories', count(*) FROM memories
      UNION ALL SELECT 'reva_subscriptions', count(*) FROM reva_subscriptions;
    "
  4. pgvector-Erweiterung verifizieren:
    docker exec reva-postgres psql -U postgres -d reva_dr_test \
      -c "SELECT extname, extversion FROM pg_extension WHERE extname = 'vector';"
  5. Aufräumen:
    docker exec reva-postgres psql -U postgres -c "DROP DATABASE reva_dr_test;"
  6. Ergebnisse dokumentieren: Datum, verwendete Backup-Datei, ob die Wiederherstellung erfolgreich war, aufgetretene Probleme und benötigte Zeit festhalten.

Was zu verifizieren ist

Ein bestandener DR-Test bestätigt, dass Ihre Backup-Strategie durchgängig funktioniert. Falls ein Schritt fehlschlägt, untersuchen und beheben Sie das Problem vor dem nächsten vierterljährlichen Test.

Diese Website verwendet keine Cookies und keine Tracking-Technologien. Schriftarten werden lokal bereitgestellt; es werden keine Daten an Dritte übermittelt. Details finden Sie in unserer Datenschutzerklärung.