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.
| Komponente | Enthält | Integriertes Backup? |
|---|---|---|
| PostgreSQL-Datenbank | Metadaten, 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:
| Typ | Wann? | Beispiel-Name |
|---|---|---|
| daily | Jeden Tag außer Sonntag/Monatserster | daily-2026-03-10 |
| weekly | Jeden Sonntag | weekly-2026-03-15 |
| monthly | Jeden 1. des Monats | monthly-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:
| Position | Wert | Bedeutung |
|---|---|---|
| Minute | 0 | Zur vollen Stunde |
| Stunde | 23 | Um 23:00 Uhr |
| Tag | * | Jeden Tag |
| Monat | * | Jeden Monat |
| Wochentag | 0,3 | Sonntag (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!

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 🙏
#Immich #FotoVerwaltung #Fotos #FotoAlbum #Docker #Linux #WSL