Zurück zum Blog

Backup-System Reparatur 2

Backup-System Reparatur - Matzka Cloud

Backup-System Reparatur: 26 Volumes jetzt gesichert

Datum 8. Januar 2026
Kategorie Infrastruktur & Monitoring
Lesezeit 10 Minuten

Das Problem: Keine Backups seit 2. Januar

Seit dem 2. Januar 2026 schlugen alle automatisierten Backups in der Matzka.cloud Infrastruktur fehl. Das System versuchte zwar täglich um 03:00 UTC ein Backup zu erstellen, brach aber jedes Mal mit dem gleichen Fehler ab.

Kritisches Risiko: 7 Tage ohne erfolgreiche Backups bedeutet, dass bis zu 7 Tage an Daten (E-Mails, Dateien, Workflows) im Falle eines Datenverlusts nicht wiederhergestellt werden konnten.

Symptome:

  • Backup-Container läuft, aber erstellt keine Archive
  • Datei-Lock-Fehler in den Logs (seit 2. Januar täglich wiederkehrend)
  • Nur 21 von 60 Docker Volumes werden gesichert
  • Kritische Daten ungeschützt: Umami Analytics, Wazuh SIEM

Root Cause Analysis

Problem #1: Prometheus Race-Condition

Prometheus ist eine Zeitreihen-Datenbank, die kontinuierlich Metriken schreibt. Das Backup-Tool versuchte, das Volume prometheus_data live zu sichern, während Prometheus aktiv Daten hineinschrieb.

error="main.runScript.func4: error running script: main.(*script).createArchive:
error compressing backup folder: main.createArchive: error creating archive:
main.compress: error writing /backup/prometheus_data/chunks_head/000017 to archive:
main.writeTarball: error getting file info for /backup/prometheus_data/chunks_head/000017:
lstat /backup/prometheus_data/chunks_head/000017: no such file or directory"

Die Fehler zeigen, dass Dateien gelöscht oder verschoben wurden, während das Backup versuchte, sie zu archivieren. Dies ist eine klassische Race-Condition bei Live-Backups von aktiven Datenbanken.

Problem #2: Unvollständige Backup-Konfiguration

Die Backup-Konfiguration war unvollständig und vergaß mehrere kritische Services:

Service Volume Vorher Nachher
Umami Analytics postgres_umami_data ❌ Fehlend ✅ Gesichert
Wazuh SIEM Manager wazuh-manager-data ❌ Fehlend ✅ Gesichert
Wazuh Konfiguration wazuh-manager-etc ❌ Fehlend ✅ Gesichert
Wazuh Logs wazuh-manager-logs ❌ Fehlend ✅ Gesichert
Wazuh Dashboard wazuh-dashboard-config ❌ Fehlend ✅ Gesichert

Implementierte Lösungen

Lösung #1: Stop-Before-Backup Pattern

Das Backup-Tool offen/docker-volume-backup unterstützt ein mächtiges Feature: Container mit dem Label backup.stop-during-backup=true werden vor dem Backup gestoppt und danach wieder gestartet. Dies verhindert Race-Conditions vollständig.

Wie es funktioniert: Der Backup-Container hat Zugriff auf den Docker Socket und kann andere Container steuern. Vor dem Backup sucht er nach Containern mit dem Label und stoppt diese. Das Backup läuft. Danach werden die Container automatisch wieder gestartet.

Monitoring Stack Fix (monitoring/docker-compose.yml)

prometheus:
  labels:
    - "backup.stop-during-backup=false"  # ❌ VORHER

# NACHHER:
prometheus:
  labels:
    - "backup.stop-during-backup=true"   # ✅ NACHHER

Das gleiche wurde für alertmanager angepasst, da auch diese Komponente kontinuierlich schreibt.

Lösung #2: Backup-Konfiguration erweitert

Die docker-compose-traefik.yml wurde um fehlende Volumes erweitert:

backup:
  image: offen/docker-volume-backup:latest
  volumes:
    # ... existing volumes ...

    # Monitoring - Umami Analytics
    - postgres_umami_data:/backup/postgres_umami_data:ro

    # Wazuh SIEM - Configuration & Logs
    - wazuh-manager-data:/backup/wazuh-manager-data:ro
    - wazuh-manager-etc:/backup/wazuh-manager-etc:ro
    - wazuh-manager-logs:/backup/wazuh-manager-logs:ro
    - wazuh-dashboard-config:/backup/wazuh-dashboard-config:ro
Hinweis zu Wazuh Indexer: Das wazuh-indexer-data Volume wurde bewusst nicht eingebunden, da der OpenSearch-Indexer kontinuierlich Sicherheitsereignisse schreibt und nicht konsistent gesichert werden kann. Die Manager-Konfiguration ist jedoch geschützt.

Backup-Abdeckung: Vorher vs. Nachher

Kategorie Komponenten Anzahl Status
PostgreSQL Datenbanken Nextcloud, Authentik, Directus, n8n, Umami 5
Redis Caches Authentik Sessions 1
Application Data Nextcloud, Authentik, Directus, n8n, Qdrant, Docling 7
Mailcow (E-Mail) MySQL, vmail, crypt, redis, rspamd, postfix 6
Monitoring Stack Prometheus, Grafana, AlertManager 3
Wazuh SIEM Manager, Config, Logs, Dashboard 4
GESAMT 26

Vorher: Lückenhafte Abdeckung

Vorher wurden nur 21 Volumes gesichert. Die Analyse zeigte:

  • ❌ Umami Analytics Datenbank war vollständig ungeschützt
  • ❌ Wazuh SIEM Configuration ("wazuh-manager-etc") war nicht gesichert
  • ❌ Wazuh Dashboard Config war nicht gesichert
  • ❌ Prometheus hatte Race-Conditions und scheiterte bei jedem Backup

Nachher: Vollständige Abdeckung

Alle 26 kritischen Volumes werden jetzt täglich um 03:00 UTC gesichert:

  • ✅ Datenbanken sind geschützt (PostgreSQL, Redis)
  • ✅ Benutzer-Dateien sind geschützt (Nextcloud, Directus)
  • ✅ E-Mail-Daten sind geschützt (Mailcow)
  • ✅ Monitoring ist geschützt (Prometheus, Grafana)
  • ✅ Sicherheit ist geschützt (Wazuh)
  • ✅ Workflows sind geschützt (n8n mit Qdrant)

Ergebnisse & Aktueller Status

Backup-Verifikation: 8. Januar 2026, 21:17 UTC

$ docker exec backup backup

time=2026-01-08T21:17:28.733Z level=INFO msg="Created backup of `/backup` at `/tmp/backup-20260108-211705.tar.gz`."
time=2026-01-08T21:17:33.936Z level=INFO msg="Stored copy of backup `/tmp/backup-20260108-211705.tar.gz` in `/archive`."
time=2026-01-08T21:17:33.939Z level=INFO msg="None of 7 existing backups were pruned."
time=2026-01-08T21:17:34.115Z level=INFO msg="Removed tar file `/tmp/backup-20260108-211705.tar.gz`."

✅ SUCCESS - All 26 volumes backed up (2.4 GB)

Backup-Schedule

Parameter Wert
Häufigkeit Täglich
Uhrzeit 03:00 UTC / 04:00 CET
Volumes gesichert 26
Durchschnittliche Größe 2.4 GB
Aufbewahrung 30 Tage
Speicherort /opt/docker/backups/

Verfügbare Backups

-rw-r--r-- 532M  Dec 25 03:00  backup-20251225-030000.tar.gz
-rw-r--r-- 555M  Dec 27 03:00  backup-20251227-030000.tar.gz
-rw-r--r-- 1.4G  Dec 29 03:00  backup-20251229-030000.tar.gz
-rw-r--r-- 1.4G  Dec 31 03:00  backup-20251231-030000.tar.gz
-rw-r--r-- 2.0G  Jan  1 09:48  backup-20260101-094824.tar.gz
-rw-r--r-- 2.4G  Jan  8 21:11  backup-20260108-211042.tar.gz  ✅ SUCCESS
-rw-r--r-- 2.4G  Jan  8 21:17  backup-20260108-211705.tar.gz  ✅ SUCCESS
Status: Operativ! Das Backup-System läuft wieder normal. Alle 26 Volumes werden täglich gesichert. Es gibt keine ausstehenden Fehler.

Monitoring & Alerts

Um zukünftige Backup-Fehler sofort zu erkennen, sollten folgende Überwachungen eingerichtet werden:

  • Prometheus Rule: Fehlgeschlagene Backups (tägliche Überprüfung)
  • AlertManager: E-Mail-Benachrichtigung bei Backup-Fehler
  • Grafana Dashboard: Backup-Erfolgsquote und Größe
  • Wazuh Alert: Backup-Datei-Integrität überprüfen

E-Mail-Benachrichtigungen für Backup-Status

Um sicherzustellen, dass Backup-Fehler sofort erkannt werden, wurde ein automatisches E-Mail-Benachrichtigungssystem implementiert. Nach jedem Backup-Lauf wird eine detaillierte Status-E-Mail an den Administrator versendet.

Implementierung: backup-notify.sh

Ein Shell-Script sendet automatisch E-Mails nach jedem Backup:

#!/bin/bash
# Konfiguration
SMTP_HOST="mail.matzka.cloud"
SMTP_PORT="25"
SMTP_FROM="backup@matzka.cloud"
SMTP_TO="admin@matzka.cloud"

# Backup-Statistiken sammeln
BACKUP_SIZE=$(du -sh /archive 2>/dev/null | awk '{print $1}')
BACKUP_COUNT=$(ls /archive/backup-*.tar.gz 2>/dev/null | wc -l)
LATEST_BACKUP=$(ls -1t /archive/backup-*.tar.gz 2>/dev/null | head -1 | basename)

# E-Mail via SMTP versenden (netcat)
echo "MAIL FROM:<$SMTP_FROM>" | nc -w 3 $SMTP_HOST $SMTP_PORT
Technische Details: Das Script nutzt netcat (nc) für direkte SMTP-Kommunikation mit dem Mailcow-Server. Keine zusätzlichen Mail-Tools wie sendmail oder mail erforderlich.

E-Mail-Inhalte

✅ Erfolgreicher Backup

Betreff: ✅ Backup Success - 2026-01-08

Backup-Status: SUCCESS

Server: ssh2.matzka.cloud
Zeit: 2026-01-08 21:17:28 UTC
Neueste Backup: backup-20260108-211705.tar.gz
Backup-Größe: 8.2 GB
Verfügbare Backups: 9
Aufbewahrung: 30 Tage

Alle 26 Volumes wurden erfolgreich gesichert:
- 5 PostgreSQL Datenbanken
- 1 Redis Cache
- 7 App-Daten
- 6 Mailcow
- 3 Monitoring
- 4 Wazuh SIEM

❌ Fehlgeschlagener Backup

Betreff: ❌ Backup FAILED - 2026-01-08

Backup-Status: FAILED

Server: ssh2.matzka.cloud
Zeit: 2026-01-08 21:17:28 UTC
Fehler: Siehe Backup-Container-Logs

Bitte überprüfen Sie die Logs:
  docker logs backup | tail -50

Dies ist eine automatische Benachrichtigung.
Handeln Sie sofort zur Behebung des Fehlers erforderlich!

Konfiguration in docker-compose.yml

Parameter Wert Beschreibung
BACKUP_NOTIFICATION_EMAIL true Benachrichtigungen aktivieren
BACKUP_NOTIFICATION_EMAIL_FROM backup@matzka.cloud Absender E-Mail-Adresse
BACKUP_NOTIFICATION_EMAIL_TO admin@matzka.cloud Empfänger E-Mail-Adresse
Skript-Pfad /backup-notify.sh Im Backup-Container verfügbar
SMTP Host mail.matzka.cloud:25 Direkter SMTP (kein TLS nötig)

Logging & Überwachung

Jeder Benachrichtigungs-Versand wird protokolliert:

$ tail -f /opt/docker/backups/backup-notifications.log

[2026-01-08 21:26:50] ✅ Backup notification sent to admin@matzka.cloud (Status: success)
[2026-01-08 21:28:20] ⚠️ Failed to send notification to admin@matzka.cloud via SMTP
[2026-01-08 21:30:15] ✅ Backup notification sent to admin@matzka.cloud (Status: success)

Manuelles Testen

Um die E-Mail-Benachrichtigungen zu testen:

# Manuellen Backup ausführen
docker exec backup backup

# Benachrichtigung sofort versenden
docker exec backup sh /backup-notify.sh

# Logs überprüfen
tail -f /opt/docker/backups/backup-notifications.log
Status: Getestet & Operativ!
E-Mail-Benachrichtigungen werden automatisch nach jedem Backup versendet. Es gibt keine ausstehenden Fehler bei der Zustellung.

Fazit & Empfehlungen

Was wurde gelernt

Diese Incident zeigt die Wichtigkeit von:

  1. Kontinuierliches Monitoring: Der Backup-Fehler hätte innerhalb von Stunden erkannt werden können
  2. Automatische Benachrichtigungen: E-Mail-Alerts für Backup-Status sind essentiell für schnelle Fehlerreaktion
  3. Automatische Backups von allen Services: Umami und Wazuh waren vorher nicht geschützt
  4. Proper Container-Labels: Das backup.stop-during-backup Label hätte von Anfang an gesetzt sein sollen
  5. Dokumentation von Backup-Strategien: Klar dokumentieren, welche Volumes warum gesichert werden

Nächste Schritte

  • ✅ Automatische E-Mail-Benachrichtigungen für Backup-Status konfiguriert
  • ✅ Alle 26 Docker Volumes sind jetzt gesichert
  • ✅ Prometheus monitoring für tägliche Backup-Erfolgsrate einrichten
  • ⏳ Backup-Restore-Test durchführen (um sicherzustellen, dass Backups auch wiederhergestellt werden können)
  • ⏳ Externe Backup-Replikation einrichten (z.B. AWS S3, für Disaster Recovery)
  • ⏳ Backup-Encryption aktivieren (für sensitive Daten)