Backup-Strategien für Docker-Infrastruktur: Der komplette Leitfaden
Backups sind das Thema, vor dem sich alle drücken. Der Server läuft, die Anwendung funktioniert, die Benutzer sind zufrieden — warum Zeit investieren in etwas, das man hoffentlich nie braucht? Die Antwort kennt jeder, der schon einmal Daten verloren hat: Ein Backup, das man nicht hat, kann man nicht restoren.
Docker macht vieles einfacher — aber Backups nicht. Volumes, Datenbanken in Containern, verteilte Konfigurationen und die Frage, wie man einen konsistenten Snapshot erstellt, wenn 10 Container gleichzeitig laufen: Das erfordert eine durchdachte Strategie. In diesem Artikel zeigen wir, wie Sie Ihre Docker-Infrastruktur zuverlässig sichern.
Die 3-2-1-Regel: Grundlage jeder Backup-Strategie
Die 3-2-1-Regel ist seit Jahrzehnten der Goldstandard:
- 3 Kopien Ihrer Daten (Original + 2 Backups)
- 2 verschiedene Medien/Speicherorte (lokal + remote)
- 1 Kopie offsite (physisch getrennt vom Server)
Angewandt auf Docker bedeutet das: Die Daten liegen im Docker-Volume (Original), werden lokal auf dem Server gesichert (Backup 1) und an einen externen Speicher übertragen (Backup 2, offsite). Wenn der Server abbrennt, die Festplatte stirbt oder ein Ransomware-Angriff alles verschlüsselt — das Offsite-Backup rettet Sie.
Was muss gesichert werden?
Ein Docker-Stack besteht aus mehreren Datenquellen, die alle gesichert werden müssen:
1. Datenbanken
MySQL/MariaDB, PostgreSQL, MongoDB — die Datenbank enthält den Kern Ihrer Anwendungsdaten. Ein Dateisystem-Snapshot der Datenbank-Dateien ist nicht ausreichend, weil die Daten im Speicher und auf der Festplatte inkonsistent sein können, wenn die Datenbank läuft.
Stattdessen: Logische Backups über die Datenbank-eigenen Tools:
# MySQL/MariaDB
docker compose exec -T database mysqldump -u root -p"$DB_ROOT_PW" --all-databases --single-transaction > backup.sql
# PostgreSQL
docker compose exec -T database pg_dump -U postgres --format=custom > backup.dump
# MongoDB
docker compose exec -T mongo mongodump --archive > backup.archive
Der Parameter --single-transaction bei MySQL ist entscheidend: Er erstellt einen konsistenten Snapshot ohne die Datenbank zu sperren — Ihre Anwendung läuft währenddessen normal weiter.
2. Docker Volumes
Volumes enthalten Anwendungsdaten, die nicht in der Datenbank liegen: hochgeladene Dateien, Medienbibliotheken, Konfigurationen, E-Mail-Speicher. Für die Sicherung gibt es mehrere Ansätze:
# Named Volumes sichern mit einem temporären Container
docker run --rm
-v myapp_data:/source:ro
-v $(pwd)/backups:/backup
alpine tar czf /backup/myapp-data-$(date +%Y%m%d).tar.gz -C /source .
# Oder direkt über den Host-Pfad (wenn bekannt)
tar czf backups/myapp-data.tar.gz -C /var/lib/docker/volumes/myapp_data/_data .
3. Docker Compose und Konfiguration
Ihre docker-compose.yml, Nginx-Konfigurationen, .env-Dateien und Custom-Configs. Diese liegen idealerweise in einem Git-Repository — das ist Ihr Konfigurationsbackup. Aber .env-Dateien mit Secrets werden nicht committet — diese müssen separat gesichert werden.
4. SSL-Zertifikate und Let’s Encrypt-Daten
Traefik speichert Zertifikate in acme.json. Verlieren Sie diese Datei, werden neue Zertifikate angefordert — das kann an Let’s Encrypts Rate Limits scheitern (maximal 5 Zertifikate pro Domain pro Woche).
Backup-Script: Ein praxistaugliches Beispiel
Ein komplettes Backup-Script für einen typischen Docker-Stack (Webanwendung + Datenbank + Volumes):
#!/bin/bash
set -euo pipefail
# Konfiguration
BACKUP_DIR="/opt/backups"
RETENTION_DAYS=30
DATE=$(date +%Y%m%d_%H%M%S)
COMPOSE_FILE="/opt/myapp/docker-compose.yml"
mkdir -p "$BACKUP_DIR/$DATE"
echo "==> Datenbank-Backup..."
docker compose -f "$COMPOSE_FILE" exec -T database
mysqldump -u root -p"$DB_ROOT_PW"
--all-databases --single-transaction
| gzip > "$BACKUP_DIR/$DATE/database.sql.gz"
echo "==> Volume-Backup..."
docker run --rm
-v myapp_uploads:/source:ro
-v "$BACKUP_DIR/$DATE":/backup
alpine tar czf /backup/uploads.tar.gz -C /source .
echo "==> Konfigurations-Backup..."
tar czf "$BACKUP_DIR/$DATE/config.tar.gz"
-C /opt/myapp
docker-compose.yml .env nginx/ config/
echo "==> Traefik-Zertifikate..."
cp /opt/traefik/acme.json "$BACKUP_DIR/$DATE/acme.json" 2>/dev/null || true
echo "==> Alte Backups aufräumen..."
find "$BACKUP_DIR" -maxdepth 1 -type d -mtime +$RETENTION_DAYS -exec rm -rf {} ;
echo "==> Backup-Größe: $(du -sh "$BACKUP_DIR/$DATE" | cut -f1)"
echo "Fertig: $BACKUP_DIR/$DATE"
Dieses Script per Cronjob täglich ausführen:
# /etc/cron.d/myapp-backup
0 3 * * * root /opt/myapp/backup.sh >> /var/log/myapp-backup.log 2>&1
Offsite-Backup: Daten vom Server wegbekommen
Ein lokales Backup schützt gegen versehentliches Löschen und Datenbankfehler. Gegen Hardware-Ausfall, Ransomware oder Rechenzentrum-Probleme hilft nur ein Offsite-Backup.
Restic: Das Schweizer Taschenmesser für Backups
Restic ist ein modernes Backup-Tool, das Deduplizierung, Verschlüsselung und inkrementelle Backups kombiniert. Es unterstützt zahlreiche Speicher-Backends:
# Repository initialisieren (einmalig)
restic -r s3:s3.eu-central-1.amazonaws.com/myapp-backups init
# Backup erstellen
restic -r s3:s3.eu-central-1.amazonaws.com/myapp-backups backup /opt/backups/latest/
# Alte Snapshots nach Retention-Policy bereinigen
restic -r s3:s3.eu-central-1.amazonaws.com/myapp-backups forget
--keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
Restic verschlüsselt alle Daten client-seitig mit AES-256. Selbst wenn der Cloud-Speicher kompromittiert wird, sind Ihre Backups sicher. Deduplizierung sorgt dafür, dass nur geänderte Datenblöcke übertragen werden — das spart Bandbreite und Speicherplatz.
BorgBackup: Die Alternative
BorgBackup bietet ähnliche Features wie Restic — Deduplizierung, Verschlüsselung, Kompression — mit leicht höherer Kompressionsrate. Der Nachteil: BorgBackup unterstützt nativ nur SSH als Remote-Backend, keine S3-Speicher.
# Repository initialisieren
borg init --encryption=repokey ssh://backup-server/./myapp
# Backup erstellen
borg create ssh://backup-server/./myapp::backup-{now:%Y%m%d} /opt/backups/latest/
# Alte Backups bereinigen
borg prune ssh://backup-server/./myapp --keep-daily=7 --keep-weekly=4 --keep-monthly=6
Offsite-Speicher-Optionen
- Hetzner Storage Box: Ab 3,81 Euro/Monat für 1 TB. Unterstützt SSH/SFTP, Samba, WebDAV. Rechenzentren in Deutschland. Ideal für BorgBackup.
- Backblaze B2: 6 USD/TB/Monat. S3-kompatible API. Ideal für Restic. Erste 10 GB kostenlos.
- AWS S3 (eu-central-1): Ab 0,023 USD/GB/Monat (Standard). Für größere Mengen S3 Glacier: 0,004 USD/GB/Monat. Bewährt, aber komplexere Preisstruktur.
- Zweiter Server: Ein günstiger VPS (5 Euro/Monat) bei einem anderen Provider als reiner Backup-Empfänger. Maximale Unabhängigkeit.
Restore testen: Die vergessene Pflicht
Ein Backup, das nie getestet wurde, ist kein Backup — es ist eine Hoffnung.
Die häufigsten Gründe, warum Restores scheitern:
- Backup ist korrupt: Der Dump-Prozess wurde unterbrochen, die Datei ist unvollständig.
- Passwort/Schlüssel fehlt: Das verschlüsselte Restic-Repository kann ohne Passwort nicht geöffnet werden — und das Passwort lag nur auf dem Server, der gerade ausgefallen ist.
- Inkompatible Version: Der MySQL-Dump wurde mit Version 8.0 erstellt, aber der neue Server läuft mit MariaDB 11. Subtile Unterschiede im SQL-Dialekt verhindern den Import.
- Volumes fehlen: Die Datenbank wurde gesichert, aber die Upload-Dateien nicht. Die Anwendung zeigt überall Broken-Image-Icons.
Restore-Test-Prozedur
Führen Sie mindestens monatlich einen vollständigen Restore-Test durch:
# 1. Temporäre Umgebung hochfahren
docker compose -f docker-compose.yml -p restore-test up -d database
# 2. Datenbank-Restore
gunzip -c backup/database.sql.gz |
docker compose -f docker-compose.yml -p restore-test exec -T database
mysql -u root -p"$DB_ROOT_PW"
# 3. Volume-Restore
docker run --rm
-v restore-test_uploads:/target
-v $(pwd)/backup:/backup:ro
alpine tar xzf /backup/uploads.tar.gz -C /target
# 4. Anwendung starten und prüfen
docker compose -f docker-compose.yml -p restore-test up -d
# 5. Aufräumen
docker compose -f docker-compose.yml -p restore-test down -v
Dokumentieren Sie das Ergebnis jedes Restore-Tests. Wie lange hat der Restore gedauert? Gab es Fehler? Waren alle Daten vollständig?
Backup-Monitoring: Wissen, ob das Backup gelaufen ist
Ein Cronjob, der stillschweigend fehlschlägt, ist schlimmer als kein Backup — weil Sie glauben, gesichert zu sein. Backup-Monitoring ist unverzichtbar:
Push-basiertes Monitoring
Das Backup-Script meldet nach erfolgreichem Lauf an einen Monitor:
# Am Ende des Backup-Scripts:
curl -s "https://uptime-kuma.example.com/api/push/abc123?status=up&msg=OK&ping=$(du -sb $BACKUP_DIR/$DATE | cut -f1)"
In Uptime Kuma einen “Push”-Monitor einrichten, der alle 25 Stunden einen Push erwartet (bei täglichen Backups). Bleibt der Push aus, wird alarmiert.
Backup-Größe überwachen
Ein Backup, das plötzlich 0 Bytes oder 90 Prozent kleiner als üblich ist, deutet auf ein Problem hin. Loggen Sie die Backup-Größe und setzen Sie Schwellwerte:
# Backup-Größe prüfen
BACKUP_SIZE=$(du -sb "$BACKUP_DIR/$DATE" | cut -f1)
MIN_SIZE=10000000 # 10 MB Minimum
if [ "$BACKUP_SIZE" -lt "$MIN_SIZE" ]; then
echo "WARNING: Backup nur $BACKUP_SIZE Bytes — erwartet mindestens $MIN_SIZE" >&2
# Alert senden
curl -s "https://ntfy.example.com/backups" -d "Backup zu klein: $BACKUP_SIZE Bytes"
exit 1
fi
Spezialfälle: Datenbanken in Docker richtig sichern
MySQL/MariaDB: Konsistente Dumps
# Alle Datenbanken, transaktionskonsistent, komprimiert
docker compose exec -T database mysqldump
-u root -p"$DB_ROOT_PW"
--all-databases
--single-transaction
--routines
--triggers
--events
| gzip > database-$(date +%Y%m%d).sql.gz
--single-transaction startet eine Transaktion vor dem Dump — die Datenbank bleibt konsistent, ohne dass Tabellen gesperrt werden. --routines, --triggers und --events sichern auch Stored Procedures und Trigger.
PostgreSQL: Custom Format für flexiblen Restore
# Custom Format — ermöglicht selektiven Restore einzelner Tabellen
docker compose exec -T database pg_dump
-U postgres
--format=custom
--blobs
mydb > mydb-$(date +%Y%m%d).dump
# Alternativ: Plain SQL für einfacheres Lesen
docker compose exec -T database pg_dumpall
-U postgres
| gzip > all-databases-$(date +%Y%m%d).sql.gz
Redis: RDB-Snapshot
# Redis zum Snapshot zwingen und Datei kopieren
docker compose exec -T redis redis-cli BGSAVE
sleep 5
docker cp $(docker compose ps -q redis):/data/dump.rdb ./backup/redis-dump.rdb
Automatisierung mit docker-volume-backup
Für Teams, die nicht jedes Backup-Script selbst schreiben wollen, bietet docker-volume-backup eine fertige Lösung als Docker-Container:
services:
backup:
image: offen/docker-volume-backup:latest
restart: unless-stopped
environment:
BACKUP_CRON_EXPRESSION: "0 3 * * *"
BACKUP_FILENAME: "backup-%Y%m%dT%H%M%S.tar.gz"
BACKUP_RETENTION_DAYS: "30"
AWS_S3_BUCKET_NAME: "myapp-backups"
AWS_ACCESS_KEY_ID: "${AWS_ACCESS_KEY_ID}"
AWS_SECRET_ACCESS_KEY: "${AWS_SECRET_ACCESS_KEY}"
# Datenbank vor dem Backup dumpen
BACKUP_PRE_COMMAND: >
docker exec $$(docker ps -qf name=database)
mysqldump -u root -p"$DB_ROOT_PW" --all-databases --single-transaction
> /tmp/pre-backup/database.sql
volumes:
- myapp_data:/backup/app-data:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
Der Container erstellt automatisch tägliche Backups, rotiert alte Sicherungen und überträgt alles an S3-kompatiblen Speicher.
Disaster Recovery: Vom Backup zum laufenden System
Ein Backup ist nutzlos, wenn Sie im Notfall nicht wissen, wie Sie es einspielen. Dokumentieren Sie Ihren Restore-Prozess:
- Neuen Server aufsetzen: Docker und Docker Compose installieren.
- Repository klonen:
git clone— Ihre docker-compose.yml und Konfiguration. - .env-Datei wiederherstellen: Aus dem Backup oder Passwort-Manager.
- Datenbank-Restore: Container starten, Dump einspielen.
- Volume-Restore: Daten in die richtigen Volumes extrahieren.
- SSL-Zertifikate: acme.json wiederherstellen oder neue anfordern.
- DNS umstellen: Domain auf die neue Server-IP zeigen lassen.
- Verifizieren: Anwendung testen, Datenintegrität prüfen.
Dieses Runbook sollte so detailliert sein, dass jemand, der den Stack nicht kennt, den Restore durchführen kann. Testen Sie es — wenn möglich mit einer Person, die nicht am Aufbau beteiligt war.
Was kostet eine gute Backup-Strategie?
- Offsite-Speicher: 4 bis 10 Euro/Monat für 100 GB bis 1 TB (Hetzner Storage Box oder Backblaze B2).
- Tools: Restic und BorgBackup sind Open Source — kostenlos.
- Arbeitszeit: Initiale Einrichtung: 2 bis 4 Stunden. Monatlicher Restore-Test: 1 Stunde. Laufende Wartung: minimal, wenn automatisiert.
Zum Vergleich: Die Kosten eines Datenverlusts — Geschäftsausfall, Wiederherstellungsversuche, verlorene Kundendaten, DSGVO-Meldepflichten — bewegen sich schnell im fünf- bis sechsstelligen Bereich. 15 Euro pro Monat für ein solides Backup-Setup ist die beste Investition, die Sie tätigen können.
Backups als Teil von Managed Hosting
Backup-Automatisierung, Offsite-Replikation und regelmäßige Restore-Tests sind integraler Bestandteil jedes professionellen Hosting-Angebots. Bei netzspitze.tech sind tägliche Backups mit 30 Tagen Retention, Offsite-Speicher und dokumentierten Restore-Prozeduren in jedem Paket enthalten.
In einem kostenlosen 15-Minuten-Call besprechen wir Ihre aktuelle Backup-Situation und wo die Lücken sind — bevor es ernst wird.