Docker Backup für Raspberry Pi: Die ultimative Anleitung zur Container-Sicherung
In diesem Artikel zeige ich dir, wie du ein komplettes Docker-Backup auf deinem Raspberry Pi erstellst. Ich habe dieses Skript entwickelt, weil ich selbst eine zuverlässige Lösung für meine Docker-Container benötigte.
Docker auf dem Raspberry Pi bietet fantastische Möglichkeiten für Home Server und IoT-Projekte. Doch ohne zuverlässiges Backup-System riskierst du den Verlust wichtiger Daten und Konfigurationen. Diese Anleitung zeigt dir, wie du eine funktionierende Backup-Lösung für deine Docker-Umgebung einrichtest.
DarkWolfCave.de
Was erwartet dich?
Mit diesem Docker Backup-Skript kannst du:
- Alle deine Docker Container sichern (egal ob sie laufen oder gestoppt sind)
- Deine Daten in den Volumes schützen
- Konfigurationen bewahren
- Eingerichtete crontabs werden gesichert
- Sichern deines HOME-Verzeichnisses
- Optional dein Backup verschlüsseln
- Automatische Integritätsprüfung der Backups
- Bei Bedarf alles wiederherstellen
Voraussetzungen
Bevor wir loslegen, stelle sicher, dass du Folgendes hast:
- Einen Raspberry Pi (egal welches Modell) oder vergleichbares
- Raspberry Pi OS (oder eine andere Linux-Distribution)
- Genug freien Speicherplatz (rechne mit dem Doppelten deiner Docker-Daten, bzw. mehr, wenn du das HOME-Verzeichnis mitsichern willst)
- Root-Rechte (sudo)
- Git für das Klonen der Docker Backup-Dateien
💡 Tipp: Am besten sicherst du die Backups direkt auf einer externen Festplatte oder auf deinem NAS
Du wirst hier einen groben Überblick finden.
Allerdings biete ich dir auch noch etwas mehr Support an:
- Du benötigst persönlichen Support
- Du möchtest von Beginn an Unterstützung bei deinem Projekt
- Du möchtest ein hier vorgestelltes Plugin durch mich installieren und einrichten lassen
- Du würdest gerne ein von mir erstelltes Script etwas mehr an deine Bedürfnisse anpassen
Für diese Punkte und noch einiges mehr habe ich einen limitierten
VIP-Patreon Tarif
eingerichtet. Falls er dir dort zurzeit nicht angeboten wird,
kontaktiere mich bitte über Discord und wir finden eine Lösung!
Installation: Schritt für Schritt
1. Benötigte Pakete installieren
Öffne zuerst ein Terminal auf deinem Pi und führe diese Befehle aus:
sudo apt-get update sudo apt-get install -y git tar gzip
Was machen wir hier genau?
apt-get update
: Aktualisiert deine Paketlisteninstall -y
: Installiert die benötigten Programme automatischgit
: Zum Herunterladen des Backup-Systemstar
undgzip
: Für die Komprimierung der Backups
2. Backup-System herunterladen
Jetzt holen wir uns das Backup-System aus meinem Git-Repository:
Solche Befehle immer nacheinander, Zeile für Zeile ausführen.
cd ~ git clone https://github.com/darkwolfcave/docker-backup-raspberry.git cd docker-backup-raspberry
🔍 Wichtig: Dieses Docker Backup Skript wird ohne jegliche Gewährleistung bereitgestellt. Ich hafte nicht für Schäden jeglicher Art oder Folgeschäden, die durch die Nutzung des Skripts entstehen.
3. Konfiguration einrichten
Nachdem du das Repository auf deinem Raspberry Pi geklont hast, müssen wir in der config noch deine persönliche Konfiguration erstellen:
cp config/config.example config/config nano config/config
In der Konfigurationsdatei findest du verschiedene Einstellungen. Lass uns die wichtigsten durchgehen:
# Hier werden deine Backups gespeichert BACKUP_BASE_DIR="/home/pi/backup" # Willst du dein HOME-Verzeichnis sichern? BACKUP_HOME=true # Diese Verzeichnisse werden NICHT gesichert EXCLUDE_DIRS=( "$RELATIVE_BACKUP_PATH" "pi/michnicht" ) # Konfiguration für Aufbewahrung DAILY_BACKUPS=7 # Letzte 7 tägliche Backups behalten WEEKLY_BACKUPS=4 # Letzte 4 wöchentliche Backups behalten MONTHLY_BACKUPS=3 # Letzte 3 monatliche Backups behalten # Verschlüsselungs-Einstellungen, falls du dein Backup verschlüsseln möchtest ENABLE_ENCRYPTION=false
💡 Mein Tipp: Lass
BACKUP_BASE_DIR
auf einem externen Speicher zeigen, wenn du ausreichend Platz hast. So sind deine Backups sicher, falls mit deiner SD-Karte bzw. USB-Stick mal etwas passiert.
4. Skripte ausführbar machen
Damit die Skripte funktionieren, müssen wir sie noch ausführbar machen:
chmod +x scripts/*.sh
Auf dieser Hardware laufen meine Umgebungen
Bei mir gibt es mehrere sogenannte »Umgebungen«, die ich benutze.
Zum einen meine »Live« oder auch »Produktion« Umgebung, auf der alles läuft, was ich in meinem Netzwerk so benötige.
Dann gibt es noch Umgebungen für unterschiedliche Szenarien: ein Labor (LAB), eine Entwickler (DEV) und eine zum finalen Testen (UAT).
Hardwaretechnisch sind aber alle fast gleich ausgestattet, da ich mit diesen Kombinationen bisher nie Probleme hatte.
Lediglich setzt meine neue Live-Umgebung erstmalig auf eine NVMe-SSD.
Werbung
Aktuelle Produktions-Umgebung (live)
Vorschau | Produkt | Preis | |
---|---|---|---|
|
Raspberry Pi 5 8 GB |
93,08 EUR |
Bei Amazon kaufen |
|
offizieller Raspberry Pi 5 USB-C Netzteil 27W, USB-C… |
18,90 EUR
14,37 EUR |
Bei Amazon kaufen |
|
GeeekPi Raspberry Pi 5 Aluminiumgehäuse mit Official… |
25,99 EUR
23,98 EUR |
Bei Amazon kaufen |
|
GeeekPi N04 M.2 M-Key NVMe SSD Shield für Raspberry Pi… |
19,99 EUR
12,95 EUR |
Bei Amazon kaufen |
|
Crucial P3 Plus SSD 1TB M.2 PCIe Gen4 NVMe Interne SSD,… |
68,70 EUR
59,99 EUR |
Bei Amazon kaufen |
|
SanDisk Extreme 32 GB microSDHC Memory Card + SD… |
14,99 EUR
9,95 EUR |
Bei Amazon kaufen |
|
Transcend 32GB kleiner und kompakter USB-Stick 3.1 Gen… |
16,14 EUR |
Bei Amazon kaufen |
|
UGREEN USB C 312MB/S Kartenleser SD 4.0 Kartenleser USB… |
25,99 EUR
19,94 EUR |
Bei Amazon kaufen |
Letzte Aktualisierung am 14.02.2025 (Preise können abweichen) / Infos zu Affiliate Links / Bilder von der Amazon Product Advertising API
Affiliate – Links
DarkWolfCave.de ist Teilnehmer des Amazon-Partnerprogramm, das zur Bereitstellung eines Mediums für Webseiten konzipiert wurde, mittels dessen durch die Platzierung von Partner-Links zu Amazon.de Entgelte verdient werden können.
Werbung
Test-Umgebungen (UAT/DEV/LAB)
Vorschau | Produkt | Preis | |
---|---|---|---|
|
Raspberry Pi 5 4GB | 74,63 EUR | Bei Amazon kaufen |
|
Raspberry Pi 4 Modell B ARM (8 GB), Linux |
86,65 EUR |
Bei Amazon kaufen |
|
Raspberry Pi 4 Modell B (4 GB) |
63,78 EUR |
Bei Amazon kaufen |
|
Raspberry 4596 Pi – offizielles Netzteil für Raspberry… | 9,99 EUR 8,45 EUR | Bei Amazon kaufen |
|
Miuzei Gehäuse für Raspberry Pi 4 mit Lüfter, 5.1V… |
18,99 EUR |
Bei Amazon kaufen |
|
SD kartenleser 5 in 1 USB 3.0, Aluminiumlegierung mit… | Bei Amazon kaufen | |
|
Samsung MZ-76E1T0B/EU 860 EVO 1 TB SATA 2,5″ Interne… |
198,63 EUR |
Bei Amazon kaufen |
|
UGREEN Festplattengehäuse 2,5 Zoll USB C 3.2 Gen 2 auf… |
19,99 EUR
13,99 EUR |
Bei Amazon kaufen |
Letzte Aktualisierung am 14.02.2025 (Preise können abweichen) / Infos zu Affiliate Links / Bilder von der Amazon Product Advertising API
Affiliate – Links
DarkWolfCave.de ist Teilnehmer des Amazon-Partnerprogramm, das zur Bereitstellung eines Mediums für Webseiten konzipiert wurde, mittels dessen durch die Platzierung von Partner-Links zu Amazon.de Entgelte verdient werden können.
Dein erstes Backup erstellen
Nachdem du die Config-Datei angepasst, gespeichert und die Skripte ausführbar gemacht hast, kannst du endlich dein erstes Docker Backup starten:
sudo ./scripts/docker_backup.sh
Was passiert jetzt im Hintergrund?
- Das Skript prüft, ob alle Voraussetzungen erfüllt sind
- Ein neues Backup-Verzeichnis wird erstellt
- Deine Crontabs werden gesichert
- Wenn aktiviert, wird dein HOME-Verzeichnis gesichert
- Alle Docker-Container werden gesichert
- Die Volumes werden gesichert
- Die Images werden gesichert
- Zum Schluss werden die Konfigurationen gesichert (sofern es welche gibt)
🚀 Pro-Tipp: Wenn du die Verschlüsselung aktiviert hast, musst du nach dem Backup manuell den Verschlüsselungsschlüssel sichern! Dieser liegt in /root/.backup_password. Bei einem Restore wird von hier versucht, den Key auszulesen. Ohne Key = keine Daten!
Automatische Docker Backups einrichten
Damit du nicht jeden Tag manuell ein Backup erstellen musst, kannst du einen Cronjob einrichten:
sudo crontab -e
Füge eine oder beide Einträge hinzu:
# Backup täglich um 3 Uhr morgens 0 3 * * * /pfad/zu/docker-backup-raspberry/scripts/docker_backup.sh # Wöchentliches Backup sonntags 2 Uhr morgens 0 2 * * 0 /pfad/zu/docker-backup-raspberry/scripts/docker_backup.sh
Was bedeutet das?
Die erste Zeile startet jeden Tag um 3 Uhr das Script:
0 3
: Um 3 Uhr morgens* * *
: Jeden Tag- Der Rest ist der Pfad zu deinem Backup-Skript
Und in der zweiten Zeile jeden Sonntag um 2 Uhr:
0
2: Um 2 Uhr morgens* *
0: Jeden Sonntag (Der Wochentag wird als Zahl von0
(Sonntag) bis6
(Samstag) dargestellt)- Der Rest ist der Pfad zu deinem Backup-Skript
Backup wiederherstellen
Solltest du ein Docker Backup wiederherstellen müssen, dann hilft dir dieser Befehl weiter. Du gibst lediglich das benötigte Backup nach dem Shell-Script mit an.
Natürlich musst du vorher dein Backup für den Raspberry erreichbar machen, falls es dort nicht (mehr) liegt.
sudo ./scripts/docker_restore.sh /pfad/zum/backup/YYYY-MM-DD_HH-MM-SS
🚀 Pro-Tipp: Überprüfe regelmäßig, ob deine Backups auch wirklich funktionieren. Am besten führst du auf einem Testsystem ein Restore mit deinen Docker-Backup-Daten durch.
Du kannst allerdings auch nur einzelne Container und Volumes wiederherstellen. Natürlich sollte dir dann der Name des Containers bzw. Volumes bekannt sein:
# Nur einen bestimmten Container sudo ./scripts/docker_restore.sh /pfad/zum/backup/YYYY-MM-DD_HH-MM-SS --container mein_container # Nur ein bestimmtes Volume sudo ./scripts/docker_restore.sh /pfad/zum/backup/YYYY-MM-DD_HH-MM-SS --volume mein_volume
Verschlüsselung nutzen
Wenn du sensible Daten hast, kannst du in der config-Datei die Verschlüsselung aktivieren: (default ist false). Im Backup und Restore Prozess würde dies dann automatisch erfolgen.
- In der
config/config
:
ENABLE_ENCRYPTION=true
- Falls du ein Backup nachträglich verschlüsseln möchtest:
./scripts/encrypt_backup.sh encrypt /pfad/zum/backup
- Und für das manuelle Entschlüsseln:
./scripts/encrypt_backup.sh decrypt /pfad/zum/backup.tar.gpg
🔍 Wichtig: Wenn du die Verschlüsselung aktiviert hast, werden deine Backups mit einem zufällig generierten Key verschlüsselt. Dieser Key wird per Default in /root/.backup_password gespeichert.
Du musst ihn manuell sichern! Bei einem Restore wird versucht, den Key von dieser Position auszulesen. Ohne Key = keine Daten!
Tipps und Tricks
Backup-Status prüfen
Wie läuft dein Backup-System? Das findest du so heraus:
./scripts/check_backup_status.sh
Das Skript zeigt dir:
- Wann das letzte Backup war
- Wie viel Platz noch frei ist
- Ob alle Backups in Ordnung sind
Alte Backups aufräumen
Damit deine Festplatte nicht vollläuft:
./scripts/cleanup_old_backups.sh
Meine persönlichen Empfehlungen
- Backup-Strategie:
- Täglich: Für aktuelle Änderungen
- Wöchentlich: Für längerfristige Sicherung
- Monatlich: Fürs Archiv
- hängt natürlich immer von deinen Anforderungen ab. Bei einem Container, indem nur HelloWorld läuft, benötigt man natürlich keine großen Backup-Strategien
- Speicherort:
- Externe NAS oder USB-Festplatte nutzen
- Mindestens zwei Backup-Generationen behalten
- Regelmäßig den Speicherplatz prüfen
- Sicherheit:
- Verschlüsselung für sensible Daten aktivieren
- Backups regelmäßig testen
- Logs im Auge behalten
- regelmäßig Restore auf einem Testsystem durchführen, um sicherzustellen, dass die Backups auch funktionieren
Fragen oder Probleme?
Wenn du Hilfe benötigst, findest du mich:
- Hier auf meinem Blog: darkwolfcave.de
- Im Discord: DarkWolfCave Discord
- Oder erstelle ein Issue auf GitHub
Detaillierte Erklärung der Docker Backup Skripte
Lass uns die einzelnen Skripte genauer anschauen, damit du verstehst, was im Hintergrund passiert.
docker_backup.sh – Das Hauptskript
Dieses Skript ist das Herzstück des Backup-Systems. Hier passiert Folgendes:
- Vorbereitung:
# Lade Konfiguration SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../config/config"
In diesem Teil wird die Config-Datei eingelesen. So kann das Script auf die Variablen und deren Werte zugreifen.
BACKUP_DATE=$(date +%Y-%m-%d_%H-%M-%S) BACKUP_DIR="$BACKUP_BASE_DIR/$BACKUP_DATE"
Mit diesen beiden Zeilen erstellt das Skript einen Ordner mit dem aktuellen Datum und der Uhrzeit. So findest du später genau das Backup, das du benötigst.
- Crontab-Sicherung:
# Crontabs sichern log "Sichere Crontabs..." mkdir -p "$BACKUP_DIR/crontabs" for user in $(cut -f1 -d: /etc/passwd); do if crontab -u $user -l > "$BACKUP_DIR/crontabs/$user.crontab" 2>/dev/null; then log "Crontab für Benutzer $user erfolgreich gesichert" else log "Keine Crontab für Benutzer $user gefunden" fi done
Hier wird für jeden Benutzer (auch System-User) auf deinem System die Crontab gesichert. Das ist wichtig, damit du später alle automatischen Aufgaben wiederherstellen kannst.
- Home-Verzeichnis sichern:
if [ "$BACKUP_HOME" = true ]; then if tar --warning=no-file-ignored -czf "$BACKUP_DIR/home.tar.gz" $(printf -- '--exclude=%s ' "${EXCLUDE_DIRS[@]}") -C "$HOME_DIR" .; then log "HOME-Verzeichnis erfolgreich gesichert" else log_error "Sicherung des HOME-Verzeichnisses fehlgeschlagen" fi else log "Sicherung des HOME-Verzeichnisses ist deaktiviert" fi
Wenn du in der Config-Datei die Home-Verzeichnis-Sicherung aktiviert hast, dann wird alles unter /home gesichert. Je nachdem wie viele User und Ordner hier sind, kann das entsprechend dauern und sehr viel Speicherplatz benötigen.
- Docker Volumes sichern:
for VOLUME in $(ls $DOCKER_VOLUMES_DIR); do if [ -d "$DOCKER_VOLUMES_DIR/$VOLUME" ]; then log "Sichere Volume: $VOLUME" if tar -czf "$BACKUP_DIR/$VOLUME.tar.gz" -C "$DOCKER_VOLUMES_DIR/$VOLUME/_data" . 2>> "$LOG_FILE"; then log "Volume $VOLUME erfolgreich gesichert" else log_error "Sicherung des Volumes $VOLUME fehlgeschlagen" fi fi done
In diesem Teil sichert das Docker Backup Skript alle durch Docker erstellte und verwaltete Volumes.
- Docker Container sichern:
# Docker Container-Konfigurationen sichern docker container ls -a --format "{{.Names}}" | xargs -I {} docker container inspect {} > $BACKUP_DIR/container_configs.json
Dieser Befehl speichert alle Informationen über deine Container – ihre Konfiguration, Volumes, Netzwerke und mehr. Die brauchen wir, um deine Container mit den entsprechenden Parametern wieder “online” zu bringen.
💡 Pro-Tipp: Wenn du wissen willst, was genau gespeichert wurde, kannst du dir die JSON-Datei mit
cat container_configs.json | jq
ansehen (falls du jq installiert hast).
- Docker Images sichern:
# Docker Images sichern log "Starte Sicherung der Docker Images..." for container in $(docker ps -aq); do name=$(docker inspect --format='{{.Name}}' $container | sed 's/\///' | tr '[:upper:]' '[:lower:]') original_name=$(docker inspect --format='{{.Name}}' $container | sed 's/\///') log "Sichere Container: $original_name" if docker commit $container ${name}_backup 2>> "$LOG_FILE" && \ docker save ${name}_backup > $BACKUP_DIR/${original_name}_backup.tar 2>> "$LOG_FILE"; then log "Container $original_name erfolgreich gesichert" else log_error "Sicherung des Containers $original_name fehlgeschlagen" fi done
Dieser Code sichert Docker-Container, indem für jeden Container ein Backup-Image erstellt und als .tar
-Datei gespeichert wird. Mit docker ps -aq
werden alle Container-IDs abgerufen und durchlaufen. Für jeden Container wird sein Name mit docker inspect
ermittelt. Dabei entfernt sed 's/\///'
den führenden /
, und tr '[:upper:]' '[:lower:]'
wandelt Großbuchstaben in Kleinbuchstaben um, um Dateinamen zu standardisieren. Parallel wird der Originalname des Containers ohne Anpassungen extrahiert. Das Backup-Image wird mit docker commit
erstellt und anschließend mit docker save
in das Backup-Verzeichnis exportiert. Fehler werden in einer Logdatei dokumentiert, während erfolgreiche Sicherungen ebenfalls protokolliert werden.
- Docker-Backup verschlüsseln (optional):
# Optional verschlüsseln if [ "$ENABLE_ENCRYPTION" = true ]; then log "Starte Backup-Verschlüsselung..." if ! "$SCRIPT_DIR/encrypt_backup.sh" encrypt "$BACKUP_DIR" 2>&1 | tee -a "$LOG_FILE"; then log_error "Verschlüsselung fehlgeschlagen" fi fi
Sofern in der Config-Datei aktiviert, wird hier ein weiteres Skript zur Verschlüsselung aufgerufen.
🔒 Sicherheitshinweis: Bewahre die Passwortdatei an einem sicheren Ort auf! Ohne sie kannst du dein Backup nicht wiederherstellen.
- Abschlussarbeiten:
# Backup-Rotation durchführen if ! "$SCRIPT_DIR/cleanup_old_backups.sh" 2>&1 | tee -a "$LOG_FILE"; then log_error "Backup-Rotation fehlgeschlagen" fi # Status-Check durchführen if ! "$SCRIPT_DIR/check_backup_status.sh" 2>&1 | tee -a "$LOG_FILE"; then log_error "Status-Check fehlgeschlagen" fi # Backup-Größe berechnen und protokollieren BACKUP_SIZE=$(du -sh "$BACKUP_DIR" | cut -f1) BACKUP_TIMESTAMP=$(stat -c %Y "$BACKUP_DIR") BACKUP_DATE=$(date -d "@$BACKUP_TIMESTAMP" '+%Y-%m-%d %H:%M:%S')
Dieser Code führt mehrere wichtige Schritte für die Verwaltung und Überprüfung deiner Backups aus:
- Backup-Rotation durchführen
Das Skriptcleanup_old_backups.sh
wird aufgerufen, um alte Backups zu entfernen und Speicherplatz freizugeben.- Der Befehl
2>&1 | tee -a "$LOG_FILE"
sorgt dafür, dass die Ausgabe sowohl im Logfile ($LOG_FILE
) gespeichert als auch auf dem Bildschirm angezeigt wird. - Tritt ein Fehler auf, wird dies mit
log_error
protokolliert und entsprechend behandelt.
- Der Befehl
- Status-Check durchführen
Das Skriptcheck_backup_status.sh
überprüft den Zustand der Backups, etwa auf Vollständigkeit oder Konsistenz. Auch hier wird die Ausgabe sowohl ins Logfile geschrieben als auch auf dem Bildschirm angezeigt. Bei einem Fehler wird eine entsprechende Fehlermeldung ausgegeben. - Backup-Größe berechnen und protokollieren
- Mit
du -sh "$BACKUP_DIR"
wird die Gesamtgröße des Backup-Verzeichnisses in einem menschenlesbaren Format berechnet (z. B. 1.2G für 1,2 Gigabyte). stat -c %Y "$BACKUP_DIR"
liefert den Unix-Zeitstempel der letzten Änderung am Backup-Verzeichnis.date -d "@$BACKUP_TIMESTAMP" '+%Y-%m-%d %H:%M:%S'
formatiert den Zeitstempel in ein lesbares Datum und eine Uhrzeit.
- Mit
Dieser Abschnitt stellt sicher, dass Backups regelmäßig aufgeräumt, überprüft und wichtige Informationen wie Größe und Datum der letzten Änderung protokolliert werden.
docker_restore.sh – Die Wiederherstellung
Dieses Skript ist dein Rettungsanker, wenn mal etwas schiefgeht oder du mit deinen Containern auf ein anderes System umziehen willst. Es arbeitet in mehreren Schritten:
- Docker Backup auf Verschlüsselung prüfen:
# Prüfe ob es sich um ein verschlüsseltes Backup handelt if [[ "$INPUT_PATH" == *.tar.gpg ]]; then log "Verschlüsseltes Backup erkannt" password_file="/root/.backup_password" if [ ! -f "$password_file" ]; then log_error "Keine Passwortdatei gefunden in $password_file" log_error "Stellen Sie sicher, dass die originale Passwortdatei vorhanden ist" exit 1 fi # Erstelle temporäres Verzeichnis für entschlüsseltes Backup temp_dir=$(dirname "$INPUT_PATH")/temp_decrypt_$(date +%s) mkdir -p "$temp_dir" log "Entschlüssele Backup..." log "Temporäres Verzeichnis: $temp_dir" if gpg --batch --yes --passphrase-file "$password_file" \ --decrypt "$INPUT_PATH" 2>/dev/null | \ tar -xzf - -C "$temp_dir" 2>/dev/null; then log "Inhalt des temp_dir nach Entschlüsselung:" ls -la "$temp_dir" >> "$RESTORE_LOG_FILE" # Finde das tatsächliche Backup-Verzeichnis in der verschachtelten Struktur BACKUP_DIR=$(find "$temp_dir" -type d -name "2???-??-??_*" -o -name "backup_*" | sort | tail -n1) if [ -z "$BACKUP_DIR" ]; then log_error "Konnte kein gültiges Backup-Verzeichnis nach Entschlüsselung finden" log_error "Verzeichnisinhalt:" ls -R "$temp_dir" | tee -a "$RESTORE_LOG_FILE" rm -rf "$temp_dir" exit 1 fi log "Backup-Verzeichnis gefunden: $BACKUP_DIR" else log_error "Fehler bei der Entschlüsselung" rm -rf "$temp_dir" exit 1 fi else BACKUP_DIR="$INPUT_PATH" fi
Dieser Code prüft, ob das angegebene Backup verschlüsselt ist, indem er auf die Dateiendung .tar.gpg
überprüft.
Erkennt er ein verschlüsseltes Backup, stellt er sicher, dass eine Passwortdatei (/root/.backup_password
) vorhanden ist, da diese für die Entschlüsselung benötigt wird.
Fehlt die Datei, bricht das Skript mit einer Fehlermeldung ab.
Ansonsten wird ein temporäres Verzeichnis erstellt, um den entschlüsselten Inhalt aufzunehmen. Mit GPG wird die Datei entschlüsselt und direkt in das temporäre Verzeichnis extrahiert. Danach durchsucht das Skript die Verzeichnisstruktur nach Ordnern, die auf ein gültiges Backup hindeuten (z. B. mit einem Datumsformat 2???-??-??_*
oder backup_*
).
Wird kein gültiges Verzeichnis gefunden, wird dies protokolliert und das temporäre Verzeichnis gelöscht.
- Backup prüfen:
if [ ! -d "$BACKUP_DIR" ]; then log_error "Backup-Verzeichnis existiert nicht: $BACKUP_DIR" exit 1 fi
Hier wird ganz einfach geprüft, ob das Backup überhaupt existiert und lesbar ist.
- Volumes wiederherstellen:
for volume_tar in $BACKUP_DIR/*.tar.gz; do docker volume create $volume_name docker run --rm -v $volume_name:/volume -v $BACKUP_DIR:/backup ubuntu tar -xzf /backup/$(basename $volume_tar) -C /volume done
Dieser Code entpackt .tar.gz
-Dateien, die in einem Backup-Verzeichnis ($BACKUP_DIR
) gespeichert sind, und stellt sie als Docker-Volumes wieder her. Zunächst wird über eine for
-Schleife jedes .tar.gz
-Archiv im angegebenen Backup-Verzeichnis ($BACKUP_DIR
) iteriert.
Für jedes Archiv wird ein Docker-Volume mit dem Namen volume_name
erstellt. Anschließend wird ein temporärer Docker-Container (mit dem Ubuntu-Image) gestartet, der das Volume ($volume_name
) und das Backup-Verzeichnis ($BACKUP_DIR
) als Volumes einbindet.
Innerhalb des Containers wird dann das Archiv ($volume_tar
) entpackt und der Inhalt in das Docker-Volume (/volume
) extrahiert. Nach Abschluss der Extraktion wird der Container automatisch entfernt (--rm
). Dieser Vorgang wird für jedes Archiv im Backup-Verzeichnis wiederholt.
⚠️ Wichtig: Bestehende Volumes werden nicht überschrieben! Lösche sie vorher, wenn du sie ersetzen möchtest.
- Crontabs wiederherstellen:
# Crontabs wiederherstellen log "Stelle Crontabs wieder her..." if [ -d "$BACKUP_DIR/crontabs" ]; then for crontab_file in "$BACKUP_DIR/crontabs"/*.crontab; do if [ -f "$crontab_file" ]; then username=$(basename "$crontab_file" .crontab) log "Stelle Crontab für Benutzer wieder her: $username" current_crontab=$(crontab -u $username -l 2>/dev/null) if [ -n "$current_crontab" ]; then if (echo "$current_crontab"; cat "$crontab_file") | crontab -u $username - 2>> "$RESTORE_LOG_FILE"; then log "Crontab für Benutzer $username erfolgreich hinzugefügt" else log_error "Fehler beim Hinzufügen der Crontab für Benutzer $username" fi else if crontab -u $username "$crontab_file" 2>> "$RESTORE_LOG_FILE"; then log "Crontab für Benutzer $username erfolgreich wiederhergestellt" else log_error "Fehler beim Wiederherstellen der Crontab für Benutzer $username" fi fi fi done
Der Codeabschnitt dient der Wiederherstellung von Crontab-Dateien für alle Benutzer aus deinem Backup-Verzeichnis.
Ablauf im Detail:
- Log-Meldung: Zu Beginn wird ein Log-Eintrag erstellt, der den Start der Wiederherstellung der Crontab-Dateien anzeigt.
- Verzeichnisprüfung: Es wird überprüft, ob im angegebenen Backup-Verzeichnis (
$BACKUP_DIR/crontabs
) ein Verzeichnis existiert, das die Crontab-Dateien enthält. Falls ja, wird der Wiederherstellungsprozess für jede Datei eingeleitet. - Durchlaufen der Crontab-Dateien: Jede
.crontab
-Datei wird einzeln durchlaufen. Der Benutzername wird anhand des Dateinamens extrahiert, wobei die Dateiendung.crontab
entfernt wird (basename "$crontab_file" .crontab
). - Aktuellen Crontab des Benutzers prüfen: Für jeden Benutzer wird geprüft, ob bereits ein Crontab existiert (
crontab -u $username -l
). Wenn der Benutzer bereits eine Crontab hat, wird der Inhalt der bestehenden Crontab mit der neuen (aus dem Backup) kombiniert und in die Crontab des Benutzers eingetragen.- Wenn eine Crontab existiert: Der bestehende Crontab-Inhalt wird mit dem Backup-Inhalt zusammengeführt und wieder in die Crontab des Benutzers geschrieben. Bei Erfolg wird eine Erfolgsnachricht im Log hinterlegt, andernfalls wird eine Fehlermeldung erzeugt.
- Wenn keine Crontab existiert: Wird keine Crontab für den Benutzer gefunden, wird die Backup-Datei direkt in die Crontab des Benutzers eingetragen.
- Fehlerbehandlung und Logging: Jede Operation, die auf die Crontab zugreift oder sie bearbeitet, wird protokolliert. Bei Fehlern wird eine entsprechende Fehlermeldung in das Wiederherstellungs-Log geschrieben (
$RESTORE_LOG_FILE
).
- Home-Verzeichnis wiederherstellen:
# HOME-Verzeichnis wiederherstellen log "Stelle HOME-Verzeichnis wieder her..." if [ -f "$BACKUP_DIR/home.tar.gz" ]; then # Finde den relativen Pfad ab docker-backup-raspberry EXCLUDE_DIR="*/docker-backup-raspberry/*" log "Exclude Backup-Tool-Verzeichnis: $EXCLUDE_DIR" if tar --warning=no-file-ignored --exclude="$EXCLUDE_DIR" -xzf "$BACKUP_DIR/home.tar.gz" -C "$HOME_DIR" 2>> "$RESTORE_LOG_FILE"; then log "HOME-Verzeichnis erfolgreich wiederhergestellt" else log_error "Fehler beim Wiederherstellen des HOME-Verzeichnisses" fi else log_error "Keine HOME-Verzeichnis-Sicherung gefunden" fi
In diesem Abschnitt wird das Home-Verzeichnis wiederhergestellt, sofern dies bei dem Backup-Prozess aktiviert und gesichert wurde. Ansonsten würde kein Home-Verzeichnis gefunden werden und eine entsprechende Meldung im Log erscheinen.
Ablauf im Detail:
- Überprüfung der Backup-Datei: Zunächst wird mit
if [ -f "$BACKUP_DIR/home.tar.gz" ]; then
überprüft, ob die Dateihome.tar.gz
im angegebenen Backup-Verzeichnis ($BACKUP_DIR
) existiert. Falls die Datei nicht vorhanden ist, wird eine Fehlermeldung im Log vermerkt:log_error "Keine HOME-Verzeichnis-Sicherung gefunden"
. - Ausschluss des Verzeichnisses “docker-backup-raspberry”: Falls die Datei vorhanden ist, wird das Backup des HOME-Verzeichnisses mit dem
tar
-Befehl wiederhergestellt. Dabei wird das Verzeichnisdocker-backup-raspberry
, das möglicherweise die Backup-Tools enthält, ausgeschlossen, um unerwünschte Daten zu vermeiden. Das geschieht mit der--exclude
Option:EXCLUDE_DIR="*/docker-backup-raspberry/*"
. Dies sorgt dafür, dass der Ordner nicht in das Zielverzeichnis entpackt wird. - Wiederherstellung mit
tar
: Der Befehltar --warning=no-file-ignored --exclude="$EXCLUDE_DIR" -xzf "$BACKUP_DIR/home.tar.gz" -C "$HOME_DIR"
entpackt das Backup (home.tar.gz
) und schließt dasdocker-backup-raspberry
-Verzeichnis aus. Die entpackten Dateien werden ins$HOME_DIR
extrahiert. Falls der Entpackungsprozess erfolgreich ist, wird eine Erfolgsmeldung im Log vermerkt:log "HOME-Verzeichnis erfolgreich wiederhergestellt"
. - Fehlerbehandlung: Falls beim Entpacken ein Fehler auftritt, wird eine Fehlernachricht erzeugt:
log_error "Fehler beim Wiederherstellen des HOME-Verzeichnisses"
. Alle Fehler werden im Log gespeichert, das unter$RESTORE_LOG_FILE
definiert ist.
- Docker Images wiederherstellen:
# Docker Images wiederherstellen log "Stelle Docker Images wieder her..." for image_tar in $BACKUP_DIR/*_backup.tar; do if [ -f "$image_tar" ]; then log "Stelle Image wieder her: $(basename $image_tar)" if docker load < $image_tar 2>> "$RESTORE_LOG_FILE"; then log "Image $(basename $image_tar) erfolgreich wiederhergestellt" else log_error "Fehler beim Wiederherstellen des Images $(basename $image_tar)" fi fi
Der Code stellt Docker-Images aus gesicherten .tar
-Dateien im angegebenen Backup-Verzeichnis wieder her. Jeder Wiederherstellungsvorgang wird im Log protokolliert, wobei sowohl erfolgreiche Wiederherstellungen als auch Fehler dokumentiert werden, um eine einfache Nachverfolgung und Fehlerbehebung zu ermöglichen.
- Docker Container wiederherstellen:
# Container wiederherstellen if [ -f "$BACKUP_DIR/docker-compose.yml" ]; then log "Stelle Container über docker-compose wieder her..." if docker-compose -f $BACKUP_DIR/docker-compose.yml up -d 2>> "$RESTORE_LOG_FILE"; then log "Container erfolgreich über docker-compose wiederhergestellt" else log_error "Fehler beim Wiederherstellen der Container über docker-compose" fi else log "Stelle einzelne Container wieder her..." if [ -f "$BACKUP_DIR/container_states.txt" ]; then while IFS=, read -r container_name container_state; do log "Stelle Container wieder her: $container_name" if docker create --name "$container_name" "${container_name}_backup" 2>> "$RESTORE_LOG_FILE"; then if [[ $container_state == *"running"* ]]; then if docker start "$container_name" 2>> "$RESTORE_LOG_FILE"; then log "Container $container_name erfolgreich gestartet" else log_error "Fehler beim Starten des Containers $container_name" fi else log "Container $container_name wurde gestoppt wiederhergestellt" fi else log_error "Fehler beim Erstellen des Containers $container_name" fi done < "$BACKUP_DIR/container_states.txt" fi fi
In diesem Part werden die Docker-Container entweder mithilfe einer docker-compose.yml
-Datei (falls eine gefunden wurde) oder einzeln basierend auf der container_states.txt
-Datei wieder hergestellt.
Dabei werden sowohl der Zustand (laufend oder gestoppt) als auch der Name jedes Containers berücksichtigt. Alle Schritte werden im Log dokumentiert, um eine Nachverfolgung des Prozesses zu ermöglichen. Fehlschläge werden ebenfalls erfasst, um eine schnelle Problembehebung zu gewährleisten.
- Berechtigungen für HOME-Verzeichnis korrigieren:
# Berechtigungen für HOME-Verzeichnis korrigieren log "Korrigiere Berechtigungen für HOME-Verzeichnis..." for user_dir in $HOME_DIR/*; do if [ -d "$user_dir" ]; then username=$(basename "$user_dir") if chown -R $username:$username "$user_dir" 2>> "$RESTORE_LOG_FILE"; then log "Berechtigungen für Benutzer $username korrigiert" else log_error "Fehler beim Korrigieren der Berechtigungen für Benutzer $username" fi fi done fi
Der Code korrigiert die Besitzrechte für jedes Benutzerverzeichnis im HOME-Verzeichnis, indem er den Besitzer und die Gruppe auf den jeweiligen Benutzernamen setzt. Der Vorgang wird für jedes Verzeichnis wiederholt und erfolgreich durchgeführte Berechtigungsänderungen sowie Fehler werden im Log dokumentiert. So wird sichergestellt, dass alle Benutzerverzeichnisse die richtigen Berechtigungen haben und keine Fehler übersehen werden.
Anpassungen an deinem Docker Backup Skript
Du kannst das Docker Backup Skript noch ein wenig nach deinen Bedürfnissen anpassen. Dies geschieht alles in der config/config:
- Backup-Rotation anpassen:
In der config kannst du die Rotationen der Backups einstellen, die vom cleanup-skript behalten werden sollen. Also per Default werden alle der letzten 7 Tage behalten, zusätzlich die letzten 4 der wöchentlichen Backups und 3 der monatlichen Backups.
DAILY_BACKUPS=7 # Die letzten 7 täglichen Backups behalten WEEKLY_BACKUPS=4 # Die letzten 4 wöchentlichen Backups behalten MONTHLY_BACKUPS=3 # Die letzten 3 monatlichen Backups behalten
- Eigene Ausschlüsse hinzufügen:
Bei EXCLUDE_DIRS kannst du beliebig viele Verzeichnisse angeben, die vom Backup-Prozess ausgeschlossen werden sollen.
EXCLUDE_DIRS=( "$RELATIVE_BACKUP_PATH" "pi/michnicht" #Beispiel für home/pi (Home Verzeichnis des Users pi) "dein/verzeichnis" # Füge hier deine eigenen Ausschlüsse hinzu )
Best Practices
- Regelmäßige Tests
- Führe monatlich Testwiederherstellungen (am besten auf einem Testsystem) durch
- Prüfe die Integrität der Backups
- Validiere die wiederhergestellten Daten
- Backup-Rotation
- Behalte mehrere Backup-Generationen
- Implementiere eine Aufbewahrungsstrategie
- Überwache den Speicherplatzverbrauch
- Sicherheit
- Aktiviere die Verschlüsselung für sensible Daten
- Beschränke den Zugriff auf Backup-Verzeichnisse
- Speichere Backups auf verschiedenen Medien
- Monitoring
- Überwache die Backup-Logs
- Richte Benachrichtigungen ein
- Prüfe regelmäßig den Backup-Status
Technische Dokumentation: Docker-Backup-System für Raspberry Pi
1. Systemübersicht
Das Docker-Backup-System ist eine Sammlung von Bash-Skripten, die entwickelt wurden, um eine umfassende Backup- und Wiederherstellungslösung für Docker-Umgebungen auf Raspberry Pi-Systemen zu bieten.
1.1 Hauptkomponenten
docker_backup.sh
: Hauptskript für den Backup-Prozessdocker_restore.sh
: Skript für die Wiederherstellung von Backupscheck_backup_status.sh
: Überwachung und Statusprüfung der Backupscleanup_old_backups.sh
: Automatische Bereinigung alter Backupsencrypt_backup.sh
: Ver- und Entschlüsselung von Backups
1.2 Unterstützende Komponenten
config
: Konfigurationsdatei für systemweite Einstellungen- Verschiedene Hilfsskripte für spezifische Aufgaben
2. Detaillierte Komponentenbeschreibung
2.1 docker_backup.sh
Zweck
Erstellt ein vollständiges Backup der Docker-Umgebung, einschließlich Container, Images, Volumes und Konfigurationen.
Hauptfunktionen
- Initialisierung:
BACKUP_DATE=$(date +%Y-%m-%d_%H-%M-%S) BACKUP_DIR="$BACKUP_BASE_DIR/$BACKUP_DATE"
- Erzeugt einen eindeutigen Zeitstempel für das Backup.
- Erstellt ein spezifisches Verzeichnis für das aktuelle Backup.
- Crontab-Sicherung:
for user in $(cut -f1 -d: /etc/passwd); do crontab -u $user -l > "$BACKUP_DIR/crontabs/$user.crontab" 2>/dev/null done
- Iteriert durch alle Systembenutzer.
- Sichert individuelle Crontab-Einträge.
- Docker-Container-Sicherung:
docker container ls -a --format "{{.Names}}" | xargs -I {} docker container inspect {} > $BACKUP_DIR/container_configs.json
- Exportiert detaillierte Konfigurationen aller Container.
- Image-Sicherung:
for container in $(docker ps -aq); do name=$(docker inspect --format='{{.Name}}' $container | sed 's/\///' | tr '[:upper:]' '[:lower:]') docker commit $container ${name}_backup docker save ${name}_backup > $BACKUP_DIR/${name}_backup.tar
- Volume-Sicherung:
for VOLUME in $(ls $DOCKER_VOLUMES_DIR); do if [ -d "$DOCKER_VOLUMES_DIR/$VOLUME" ]; then tar -czf "$BACKUP_DIR/$VOLUME.tar.gz" -C "$DOCKER_VOLUMES_DIR/$VOLUME/_data" . fi done
- Iteriert durch alle Docker-Volumes
- Verwendet tar mit Komprimierung (-czf)
- Sichert nur den /_data Unterordner der Volumes
- Behält die Verzeichnisstruktur bei
- Fehlerbehandlung:
log_error() { local message="[$(date '+%Y-%m-%d %H:%M:%S')] FEHLER: $1" echo "$message" | tee -a "$LOG_FILE" >&2 }
- Zentralisierte Fehlerbehandlung
- Timestamps für alle Fehlereinträge
- Duale Ausgabe (STDERR und Logfile)
- Fehler-Kontext wird beibehalten
2.2 docker_restore.sh
- Initialisierung und Validierung:
RESTORE_DATE=$(date +%Y-%m-%d_%H-%M-%S) if [ ! -d "$BACKUP_DIR" ]; then log_error "Backup-Verzeichnis existiert nicht: $BACKUP_DIR" exit 1 fi
- Präzise Zeitstempelgenerierung
- Strikte Verzeichnisvalidierung
- Früher Abbruch bei Fehlern
- Wiederherstellungslogik:
restore_single_container() { local backup_dir="$1" local container_name="$2" if [ ! -f "$backup_dir/${container_name}_backup.tar" ]; then log_error "Backup für Container $container_name nicht gefunden" return 1 fi }
- Modularer Aufbau durch Funktionen
- Einzelcontainer-Wiederherstellung möglich
- Granulare Fehlerkontrolle
2.3 check_backup_status.sh
Technische Spezifikation
- Backup-Alter-Analyse:
check_backup_age() { backup_timestamp=$(stat -c %Y "$latest_backup") current_timestamp=$(date +%s) seconds_old=$((current_timestamp - backup_timestamp)) days_old=$((seconds_old / 86400)) }
- Verwendet Unix-Timestamps für präzise Zeitberechnungen
- Berücksichtigt Zeitzonen-Unabhängigkeit
- Effiziente Berechnung ohne externe Tools
- Speicherplatz-Monitoring:
check_backup_size() { local available_kb=$(df "$BACKUP_BASE_DIR" | awk 'NR==2 {print $4}') local total_kb=$(df "$BACKUP_BASE_DIR" | awk 'NR==2 {print $2}') if [ $((available_kb * 100 / total_kb)) -lt 20 ]; then log "WARNUNG: Wenig Speicherplatz verfügbar!" return 1 fi }
- Proaktives Speicherplatz-Monitoring
- Prozentuale Berechnung
- Schwellenwert-basierte Warnungen
2.4 cleanup_old_backups.sh
- Backup-Rotation:
mapfile -t backups < <(find "$BACKUP_BASE_DIR" -maxdepth 1 -type d -name "????-??-??_*" | sort)
- Verwendet mapfile für effiziente Array-Operationen
- Reguläre Ausdrücke für präzise Backup-Identifikation
- Sortierung nach Zeitstempel
- Retention-Logik:
retain_backups() { local -r daily_keep="$DAILY_BACKUPS" local -r weekly_keep="$WEEKLY_BACKUPS" local -r monthly_keep="$MONTHLY_BACKUPS" }
- Konfigurierbares Retention-Management
- Hierarchische Backup-Strategie
- Konstante Speichernutzung
2.5 encrypt_backup.sh
- Verschlüsselungslogik:
encrypt_backup() { local backup_dir="$1" local output_file="${backup_dir}.tar.gpg" local password_file="/root/.backup_password" }
Sicherheitsaspekte:
- GPG-basierte Verschlüsselung
- Sichere Passwort-Verwaltung
- Datei-basierter Schlüsselaustausch
3. Datenfluss und Interaktionen
3.1 Systemkomponenten-Interaktion
sequenceDiagram participant Backup Script participant Docker API participant Filesystem participant Encryption Backup Script->>Docker API: Container Inspection Docker API-->>Backup Script: Container Metadata Backup Script->>Filesystem: Write Backup Filesystem-->>Backup Script: Confirmation Backup Script->>Encryption: Optional Encryption
3.2 Datenformat-Spezifikationen
- Container-Konfiguration:
{ "Name": "container_name", "State": { "Status": "running", "Running": true }, "Config": { "Env": [], "Volumes": {} } }
- Backup-Verzeichnisstruktur:
YYYY-MM-DD_HH-MM-SS/ ├── container_configs.json ├── container_states.txt ├── volumes/ │ ├── volume1.tar.gz │ └── volume2.tar.gz ├── images/ │ └── image_backup.tar └── crontabs/ └── user.crontab