Du betrachtest gerade Immich Backup Automatisierung Skript | Volle automatische Sicherung

Immich Backup Automatisierung Skript | Volle automatische Sicherung

Immich Backup Automatisierung Skript, die vollwertige Immich Sicherung mit allen Daten inkl. Fotos und Videos. Zwar bietet Immich integrierte Backup-Funktionen, aber diese sichern nur die Datenbank – nicht deine wertvollen Fotos und Videos! Für eine wirklich vollständige Sicherung brauchst du beides.

KomponenteEnthältIntegriertes Backup?
PostgreSQL-DatenbankMetadaten, Alben, Gesichtserkennung, Tags✅ Ja (tägliche Dumps)
Medien (Fotos/Videos)Deine Originaldateien❌ Nein

Die goldene Regel: Datenbank zuerst sichern, dann die Medien. So vermeidest du „tote Links“ in der Wiederherstellung – Fotos, die in der Datenbank existieren, aber physisch fehlen. Der zeitliche Abstand zwischen beiden Backups sollte minimal sein.

Unser Skript erledigt genau das: Erst die Datenbank, dann die Medien – automatisch, zuverlässig und platzsparend.

Video: Immich Backup Automatisierung Skript | Volle automatische Sicherung

Sprache: 🇩🇪|🇬🇧
☝️ Benutze YouTube Untertitel für alle Sprachen.

Installation von rsync unter Linux

# rsync installieren (Ubuntu/Debian)
sudo apt update
sudo apt install rsync -y

# Installation prüfen
rsync --version

Script-Beschreibung

Das Skript liegt im Verzeichnis deiner docker-compose.yml (z.B. /mnt/d/Visual Edit/immich/backup_immich.sh). Die wichtigsten Konfigurationsbereiche:

Konfiguration (anpassen!)

# ---------- KONFIGURATION ----------
SOURCE="/mnt/d/Visual Edit/immich/medien/"
DEST_BASE="/mnt/d/backups/immich"
LOG="$DEST_BASE/backup.log"

# Aufbewahrungsdauer (in Tagen)
KEEP_DAILY=7      # Tägliche Backups 7 Tage behalten
KEEP_WEEKLY=30    # Wöchentliche 30 Tage (ca. 4 Wochen)
KEEP_MONTHLY=365  # Monatliche 365 Tage (1 Jahr)

# PostgreSQL Container
DB_CONTAINER="immich_postgres"
DB_USER="postgres"

Intelligente Backup-Typen

Das Skript unterscheidet automatisch:

TypWann?Beispiel-Name
dailyJeden Tag außer Sonntag/Monatsersterdaily-2026-03-10
weeklyJeden Sonntagweekly-2026-03-15
monthlyJeden 1. des Monatsmonthly-2026-04-01

Das vollständige Backup-Skript

WICHTIG !

Beachte das rsync nicht mit der Anzahl der Sicherung arbeitet. Damit man nicht zwei Werte Konfigurieren muss, wird der Wert als “ sondern „älter als xx Tage“ verarbeitet. Was Älter ist wird gelöscht, je nach Sicherung Daily, Weekly, Monthly.

# Aufbewahrungsdauer (in Tagen)
KEEP_DAILY=7 # Behalte tägliche Backups, die jünger als 7 Tage sind
KEEP_WEEKLY=30 # Behalte wöchentliche Backups, die jünger als 30 Tage sind
KEEP_MONTHLY=365 # Behalte monatliche Backups, die jünger als 365 Tage sind

#!/bin/bash

# =====================================================
# IMMICH POWER-BACKUP mit rsync (Hardlink-Modus)
# =====================================================
# Autor      | KSC, Michael Kissner
# Hiomepage  | www.klissner.uk
# Version    | 2.0 
#
# 🇬🇧 Link for Support / donation for the channel:
# 🇩🇪 Link zur Unterstützung / Spende für denn Kanal: 
# PayPal: https://www.paypal.com/donate?hosted_button#MEAN_id=G8CZWPDCM3SNW
# Bank, Bitcoin und Lightning: https://www.ksc-llp.uk/donateyoutube
# =====================================================

#!/bin/bash

# =====================================================
# IMMICH POWER-BACKUP mit rsync (Hardlink-Modus) - KORRIGIERT
# =====================================================

# ---------- KONFIGURATION ----------
SOURCE="/mnt/d/Visual Edit/immich/medien/"
DEST_BASE="/mnt/d/backups/immich/"
LOG="$DEST_BASE/backup.log"

# Aufbewahrungsdauer (in Tagen)
KEEP_DAILY=3       # Behalte tägliche Backups, die jünger als 7 Tage sind
KEEP_WEEKLY=14     # Behalte wöchentliche Backups, die jünger als 30 Tage sind  
KEEP_MONTHLY=60    # Behalte monatliche Backups, die jünger als 365 Tage sind

# PostgreSQL Container Name
DB_CONTAINER="immich_postgres"
DB_USER="postgres"
DB_NAME="immich"

# ---------- DATUM ERMITTELN ----------
DATE=$(date +%Y-%m-%d)
YEAR=$(date +%Y)
MONTH=$(date +%m)
DAY=$(date +%d)
DOW=$(date +%u)   # 1=Montag, 7=Sonntag

# ---------- BACKUP-TYP BESTIMMEN ----------
# Monatlich? (Am ersten Tag des Monats)
if [ "$DAY" == "01" ]; then
    BACKUP_TYPE="monthly"
    BACKUP_NAME="monthly-$YEAR-$MONTH"
# Wöchentlich? (Sonntag = 7)
elif [ "$DOW" == "7" ]; then
    BACKUP_TYPE="weekly"
    BACKUP_NAME="weekly-$YEAR-W$((($(date +%V))))"  # Kalenderwoche
# Täglich (alle anderen Tage)
else
    BACKUP_TYPE="daily"
    BACKUP_NAME="daily-$DATE"
fi

# ---------- PFADE FESTLEGEN ----------
DEST="$DEST_BASE/$BACKUP_NAME"
LATEST_LINK="$DEST_BASE/latest"
DB_BACKUP_DIR="$DEST/database"
DB_BACKUP_FILE="$DB_BACKUP_DIR/immich-db-$DATE.sql"

# ---------- LOGGING-FUNKTION ----------
log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1"
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG"
}

# ========== HAUPTPROGRAMM ==========
# Log-Verzeichnis erstellen
mkdir -p "$DEST_BASE"

log "========================================="
log "BACKUP GESTARTET - Typ: $BACKUP_TYPE"
log "========================================="

# Prüfungen
if [ ! -d "$SOURCE" ]; then
    log "FEHLER: Quelle $SOURCE existiert nicht!"
    log "Aktuelles Verzeichnis: $(pwd)"
    exit 1
fi

# Prüfe ob Docker-Container läuft
if ! docker ps | grep -q "$DB_CONTAINER"; then
    log "WARNUNG: PostgreSQL Container $DB_CONTAINER läuft nicht - Datenbank-Backup wird übersprungen"
    DB_AVAILABLE=false
else
    DB_AVAILABLE=true
fi

# Zielordner erstellen
mkdir -p "$DEST"
mkdir -p "$DB_BACKUP_DIR"
log "Zielordner: $DEST"

# ========== DATENBANK-BACKUP ==========
if [ "$DB_AVAILABLE" = true ]; then
    log "Starte Datenbank-Backup..."
    
    # pg_dumpall erstellt ein komplettes Backup aller Datenbanken und Rollen
    docker exec "$DB_CONTAINER" pg_dumpall -U "$DB_USER" > "$DB_BACKUP_FILE" 2>> "$LOG"
    
    if [ $? -eq 0 ]; then
        # Komprimieren um Platz zu sparen
        gzip -f "$DB_BACKUP_FILE"
        log "✅ Datenbank-Backup erfolgreich: $DB_BACKUP_FILE.gz"
        
        # Größe anzeigen
        DB_SIZE=$(du -h "$DB_BACKUP_FILE.gz" | cut -f1)
        log "   Größe: $DB_SIZE"
    else
        log "❌ FEHLER: Datenbank-Backup fehlgeschlagen!"
    fi
else
    log "⚠️ Datenbank-Backup übersprungen (Container nicht verfügbar)"
fi

# ========== FOTO-BACKUP MIT HARDLINKS ==========
log "Starte rsync für Fotos (Hardlink-Modus)..."

# WICHTIG: Quellpfad mit Slash am Ende für korrekte Inhaltskopie
SOURCE_WITH_SLASH="${SOURCE%/}/"

if [ -d "$LATEST_LINK" ] && [ -d "$LATEST_LINK/medien" ]; then
    # Hardlinks zum letzten Backup verwenden
    rsync -a --delete \
          --link-dest="$LATEST_LINK/medien" \
          "$SOURCE_WITH_SLASH" \
          "$DEST/medien/" >> "$LOG" 2>&1
else
    # Erstes Backup
    rsync -a "$SOURCE_WITH_SLASH" "$DEST/medien/" >> "$LOG" 2>&1
fi

if [ $? -eq 0 ]; then
    log "✅ rsync erfolgreich abgeschlossen"
    
    # Latest-Link aktualisieren
    rm -f "$LATEST_LINK"
    ln -s "$DEST" "$LATEST_LINK"
    log "✅ Latest-Link aktualisiert"
    
    # Größe des Foto-Backups ermitteln
    if [ -d "$DEST/medien" ]; then
        PHOTO_SIZE=$(du -sh "$DEST/medien" | cut -f1)
        log "   Größe Fotos: $PHOTO_SIZE"
    fi
else
    log "❌ FEHLER: rsync fehlgeschlagen!"
    exit 1
fi

# ========== AUFRÄUMEN ALTER BACKUPS ==========
log "Starte Aufräumen alter Backups..."

# Sicherstellen, dass wir im richtigen Verzeichnis sind
if ! cd "$DEST_BASE"; then
    log "FEHLER: Kann nicht nach $DEST_BASE wechseln!"
    exit 1
fi

# Aufräumen basierend auf Backup-Typ und Alter - KORRIGIERT
# Lösche tägliche Backups, die älter als KEEP_DAILY sind
find . -maxdepth 1 -type d -name "daily-*" -mtime +$KEEP_DAILY 2>/dev/null | while read dir; do
    log "Lösche altes tägliches Backup: $dir"
    rm -rf "$dir"
done

# Lösche wöchentliche Backups, die älter als KEEP_WEEKLY sind
find . -maxdepth 1 -type d -name "weekly-*" -mtime +$KEEP_WEEKLY 2>/dev/null | while read dir; do
    log "Lösche altes wöchentliches Backup: $dir"
    rm -rf "$dir"
done

# Lösche monatliche Backups, die älter als KEEP_MONTHLY sind
find . -maxdepth 1 -type d -name "monthly-*" -mtime +$KEEP_MONTHLY 2>/dev/null | while read dir; do
    log "Lösche altes monatliches Backup: $dir"
    rm -rf "$dir"
done

# ========== ZUSAMMENFASSUNG ==========
log "========================================="
log "BACKUP ABGESCHLOSSEN"
log "Typ: $BACKUP_TYPE"
log "Ziel: $DEST"
log "  - Datenbank: $([ "$DB_AVAILABLE" = true ] && echo "✅" || echo "⚠️ übersprungen")"
log "  - Fotos: ✅ (Hardlinks aktiv)"
log "Aufbewahrung:"
log "  - Täglich: $KEEP_DAILY Tage"
log "  - Wöchentlich: $KEEP_WEEKLY Tage"
log "  - Monatlich: $KEEP_MONTHLY Tage"
log "========================================="

Hinweis: Vergesse nicht die Datei backup_immich.sh als „ausführbar“ zu berechtigen:

chmod +x backup_immich.sh

Sonst kann das Skript nicht gestartet werden!

Crontab-Einrichtung (Linux/WSL)

Wichtig: Windows Task Scheduler funktioniert hier nicht zuverlässig, da WSL-Instanzen im Hintergrundmodus Probleme machen. Die Lösung ist Cron innerhalb deiner WSL-Umgebung:

# Crontab öffnen
crontab -e

# Folgende Zeile einfügen (Mi+So um 23:00):
0 23 * * 0,3 /mnt/d/Visual\ Edit/immich/backup_immich.sh >> /home/mike/cron.log 2>&1

# Speichern und schließen

Crontab-Erklärung:

PositionWertBedeutung
Minute0Zur vollen Stunde
Stunde23Um 23:00 Uhr
Tag*Jeden Tag
Monat*Jeden Monat
Wochentag0,3Sonntag (0) und Mittwoch (3)

Cron testen:

# Prüfen, ob Cron läuft
sudo service cron status

# Crontab anzeigen
crontab -l

# Logs prüfen
cat /home/mike/cron.log

Zusammenfassung

Dein Backup-System jetzt:

  • Vollständig (Datenbank + Fotos)
  • Automatisch (Mi+So 23:00)
  • Platzsparend (Hardlinks)
  • Versioniert (daily/weekly/monthly)
  • Wiederherstellbar (jeder Snapshot)

Genieße die Sicherheit – deine Fotos sind jetzt wirklich geschützt!


Spenden Bild

Link zur Unterstützung / Spende für den Kanal
Wenn meine Beiträge hilfreich sind oder dir geholfen haben, würde ich mich über eine Unterstützung sehr freuen 🙏

PayPal Link
Überweisung, Bitcoin und Lightning


#Immich #FotoVerwaltung #Fotos #FotoAlbum  #Docker #Linux #WSL  

Schreibe einen Kommentar