5
(4)

Docker Backup für Raspberry Pi: Die ultimative Anleitung zur Container-Sicherung

Erstellt / aktualisiert

wichtige Informationen...

Affiliate - Offenlegung

Auf meiner Seite verwende ich sogenannte Affiliate-Links, diese sind mit einem gekennzeichnet, damit du diese auch direkt erkennen kannst.
Sobald du über so einen Link das Produkt kaufen würdest, erhalte ich möglicherweise eine Provision vom jeweiligen Anbieter. Außerdem entstehen für Dich natürlich keine zusätzlichen Kosten!
Mich unterstützt du damit aber enorm und trägst dazu bei, dass es auch in Zukunft weitere Guides und Vorstellungen von mir hier geben wird.

Ich empfehle nur Tools / PlugIns / Anbieter / Produkte, hinter denen ich auch wirklich stehe, bzw. bei denen ich auch einen Mehrwert sehe.

DarkWolfCave.de ist Teilnehmer des Amazon-Partnerprogramms, 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.


ACHTUNG! Bitte lesen!

Du benutzt das hier Gezeigte natürlich, wie immer, auf eigenes Risiko!
Ich habe alles selbst durchgeführt und mir mein System nicht zerschossen oder sonst irgendwelche negativen Auffälligkeiten bemerkt.

Aber dennoch… Backups sind immer gut….
Für WordPress-Backups am besten mit UpdraftPlus

Ich übernehme keine Haftung für Schäden jeglicher Art am System, der Hardware oder der Katze…. :-P


DarkWolfCave.de

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
📋 Setup-Checkliste

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 Paketlisten
  • install -y: Installiert die benötigten Programme automatisch
  • git: Zum Herunterladen des Backup-Systems
  • tar und gzip: 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
DarkWolfCave - Raspberry Pi

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

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

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?

  1. Das Skript prüft, ob alle Voraussetzungen erfüllt sind
  2. Ein neues Backup-Verzeichnis wird erstellt
  3. Deine Crontabs werden gesichert
  4. Wenn aktiviert, wird dein HOME-Verzeichnis gesichert
  5. Alle Docker-Container werden gesichert
  6. Die Volumes werden gesichert
  7. Die Images werden gesichert
  8. 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 von 0 (Sonntag) bis 6 (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.

  1. In der config/config:
ENABLE_ENCRYPTION=true
  1. Falls du ein Backup nachträglich verschlüsseln möchtest:
./scripts/encrypt_backup.sh encrypt /pfad/zum/backup
  1. 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

DarkWolfCave.de - Docker Backup Script - durchschnittliche Backup-Größen

Damit deine Festplatte nicht vollläuft:

./scripts/cleanup_old_backups.sh

Meine persönlichen Empfehlungen

  1. 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
  1. Speicherort:
  • Externe NAS oder USB-Festplatte nutzen
  • Mindestens zwei Backup-Generationen behalten
  • Regelmäßig den Speicherplatz prüfen
  1. 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:

Detaillierte Erklärung der Docker Backup Skripte

Lass uns die einzelnen Skripte genauer anschauen, damit du verstehst, was im Hintergrund passiert.

DarkWolfCave.de - Docker Backup Script - Programmablaufplan

docker_backup.sh – Das Hauptskript

Dieses Skript ist das Herzstück des Backup-Systems. Hier passiert Folgendes:

  1. 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.

  1. 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.

  1. 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.

  1. 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.

  1. 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).

  1. 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.

  1. 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.

  1. 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:

  1. Backup-Rotation durchführen
    Das Skript cleanup_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.
  2. Status-Check durchführen
    Das Skript check_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.
  3. 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.

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:

  1. 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.

  1. 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.

  1. 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.

  1. 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:

  1. Log-Meldung: Zu Beginn wird ein Log-Eintrag erstellt, der den Start der Wiederherstellung der Crontab-Dateien anzeigt.
  2. 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.
  3. 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).
  4. 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.
  5. 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).
  1. 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:

  1. Überprüfung der Backup-Datei: Zunächst wird mit if [ -f "$BACKUP_DIR/home.tar.gz" ]; then überprüft, ob die Datei home.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".
  2. 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 Verzeichnis docker-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.
  3. Wiederherstellung mit tar: Der Befehl tar --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 das docker-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".
  4. 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.
  1. 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.

  1. 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.

  1. 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:

  1. 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
  1. 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

  1. Regelmäßige Tests
  • Führe monatlich Testwiederherstellungen (am besten auf einem Testsystem) durch
  • Prüfe die Integrität der Backups
  • Validiere die wiederhergestellten Daten
  1. Backup-Rotation
  • Behalte mehrere Backup-Generationen
  • Implementiere eine Aufbewahrungsstrategie
  • Überwache den Speicherplatzverbrauch
  1. Sicherheit
  • Aktiviere die Verschlüsselung für sensible Daten
  • Beschränke den Zugriff auf Backup-Verzeichnisse
  • Speichere Backups auf verschiedenen Medien
  1. 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

  1. docker_backup.sh: Hauptskript für den Backup-Prozess
  2. docker_restore.sh: Skript für die Wiederherstellung von Backups
  3. check_backup_status.sh: Überwachung und Statusprüfung der Backups
  4. cleanup_old_backups.sh: Automatische Bereinigung alter Backups
  5. encrypt_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

DarkWolfCave.de - Docker Backup Skript - Architektur & Workflow

2.1 docker_backup.sh

Zweck

Erstellt ein vollständiges Backup der Docker-Umgebung, einschließlich Container, Images, Volumes und Konfigurationen.

Hauptfunktionen

  1. 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.
  1. 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.
  1. Docker-Container-Sicherung:
   docker container ls -a --format "{{.Names}}" | xargs -I {} docker container inspect {} > $BACKUP_DIR/container_configs.json
  • Exportiert detaillierte Konfigurationen aller Container.
  1. 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
  1. 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
  1. 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

  1. 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
  1. 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

  1. 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
  1. 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

  1. 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
  1. 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

  1. 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

  1. Container-Konfiguration:
{
    "Name": "container_name",
    "State": {
        "Status": "running",
        "Running": true
    },
    "Config": {
        "Env": [],
        "Volumes": {}
    }
}
  1. 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
Avatar-Foto

Ich bin ein 1977 geborener Technik-Nerd. Mein erster Gefährte in der digitalen Welt war ein C64, der den Grundstein für meine Leidenschaft für Technologie legte. So wurde mein Hobby zum Beruf, und ich begann eine Ausbildung zum IT-Systemelektroniker. Selbst in meiner knappen Freizeit widme ich mich weiterhin meiner Leidenschaft fürs Gaming, verschiedene Programmiersprachen und andere IT-bezogene Themen. Ansonsten mag ich Hunde und bin fasziniert von Wölfen!

Gefällt dir der Beitrag?
Hinterlasse gerne ein paar Sterne!

Wie hilfreich war dieser Beitrag für Dich?

Klicke auf die Sterne um zu bewerten!

Durchschnittliche Bewertung 5 / 5. Anzahl Bewertungen: 4

Bisher keine Bewertungen! Sei der Erste, der diesen Beitrag bewertet.

Es tut uns leid, dass der Beitrag für dich nicht hilfreich war!

Lasse uns diesen Beitrag verbessern!

Wie können wir diesen Beitrag verbessern?

Abonnieren
Benachrichtige mich bei
guest
0 Kommentare
Neueste
Älteste
Inline Feedbacks
Alle Kommentare anzeigen

GitHub - Sourcecode

Den gesamten und aktuellen Sourcecode meiner Scripte, Snippets und Tools findest du ab jetzt auch in meinem GitHub Account!
Inhalt