Pragmatische Technik aus der Praxis

Mein Paperless-NGX Backup-Konzept: Automatisiert, sicher und zuverlässig

TL;DR

Automatisches Backup-System für Paperless-NGX mit täglichen Backups, wöchentlicher Rotation und optionalem Offsite-Transfer. Alles läuft via Cron-Job und einem simplen Bash-Script.

Warum überhaupt Backups?

Paperless-NGX ist großartig – alle Dokumente digitalisiert, durchsuchbar und ordentlich organisiert. Aber was passiert, wenn die Festplatte den Geist aufgibt, ein Update schiefgeht oder man sich aus Versehen die Datenbank zerschießt? Genau: Game Over. 

Deshalb habe ich mir ein Backup-Konzept gebaut, das automatisch läuft und mich nachts ruhig schlafen lässt.

Das Konzept

Die Anforderungen

  • Automatisch: Kein manuelles Eingreifen nötig
  • Vollständig: Datenbank, Medien und Konfiguration
  • Versioniert: Mehrere Backup-Generationen
  • Offsite-fähig: Optional auf externen Speicher (NAS, Cloud, etc.)
  • Ressourcenschonend: Läuft nachts, wenn eh nichts los ist

Die Backup-Strategie

Ich setze auf ein 3-2-1-Prinzip (oder zumindest so nah wie möglich dran):

  • 3 Kopien der Daten (Produktiv + 2 Backups)
  • 2 verschiedene Medien (lokale Festplatte + NAS/Cloud)
  • 1 Offsite-Kopie (außerhalb des Servers)

Backup-Rotation

  • Täglich: Die letzten 7 Tage
  • Wöchentlich: Die letzten 4 Wochen
  • Optional: Monatliche Backups für längere Aufbewahrung

Das Backup-Script

Das Script macht folgendes:

  1. Stoppt Paperless-Container (optional, für konsistente Backups)
  2. Exportiert die PostgreSQL-Datenbank
  3. Packt alles zusammen: DB-Dump, Media-Files, Config
  4. Erstellt ein komprimiertes Archiv mit Timestamp
  5. Startet Paperless wieder
  6. Löscht alte Backups nach Rotation-Schema
  7. Optional: Sync zu externem Speicher
#!/bin/bash

###############################################################################
# Paperless-NGX Backup Script
# Erstellt vollständige Backups inkl. Datenbank, Medien und Konfiguration
###############################################################################

# Konfiguration
PAPERLESS_DIR="/opt/paperless-ngx"
BACKUP_DIR="/mnt/backups/paperless"
COMPOSE_FILE="$PAPERLESS_DIR/docker-compose.yml"
RETENTION_DAYS=7
RETENTION_WEEKS=4

# Optional: Offsite Backup (NAS, rsync, rclone, etc.)
OFFSITE_ENABLED=false
OFFSITE_DEST="/mnt/nas/backups/paperless"

# Timestamp für Backup
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
BACKUP_NAME="paperless_backup_$TIMESTAMP"
TEMP_DIR="/tmp/$BACKUP_NAME"

# Logging
LOG_FILE="$BACKUP_DIR/backup.log"

log() {
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

# Backup-Verzeichnis erstellen
mkdir -p "$BACKUP_DIR"
mkdir -p "$TEMP_DIR"

log "=== Paperless-NGX Backup gestartet ==="

# 1. Container stoppen (optional - für konsistente Backups)
log "Stoppe Paperless-Container..."
cd "$PAPERLESS_DIR" || exit 1
docker compose -f "$COMPOSE_FILE" stop webserver

# 2. Datenbank exportieren
log "Exportiere PostgreSQL-Datenbank..."
docker compose -f "$COMPOSE_FILE" exec -T db pg_dump -U paperless paperless > "$TEMP_DIR/database.sql"

if [ $? -eq 0 ]; then
    log "Datenbank-Export erfolgreich"
else
    log "FEHLER: Datenbank-Export fehlgeschlagen!"
    docker compose -f "$COMPOSE_FILE" start webserver
    exit 1
fi

# 3. Media-Files kopieren
log "Kopiere Media-Files..."
cp -r "$PAPERLESS_DIR/media" "$TEMP_DIR/"
cp -r "$PAPERLESS_DIR/data" "$TEMP_DIR/"

# 4. Konfiguration sichern
log "Sichere Konfiguration..."
cp "$PAPERLESS_DIR/docker-compose.yml" "$TEMP_DIR/"
cp "$PAPERLESS_DIR/.env" "$TEMP_DIR/" 2>/dev/null || log "Keine .env Datei gefunden"

# 5. Container wieder starten
log "Starte Paperless-Container..."
docker compose -f "$COMPOSE_FILE" start webserver

# 6. Backup komprimieren
log "Komprimiere Backup..."
cd /tmp || exit 1
tar -czf "$BACKUP_DIR/$BACKUP_NAME.tar.gz" "$BACKUP_NAME"

if [ $? -eq 0 ]; then
    log "Backup erfolgreich erstellt: $BACKUP_NAME.tar.gz"
    BACKUP_SIZE=$(du -h "$BACKUP_DIR/$BACKUP_NAME.tar.gz" | cut -f1)
    log "Backup-Größe: $BACKUP_SIZE"
else
    log "FEHLER: Backup-Komprimierung fehlgeschlagen!"
    exit 1
fi

# Temp-Verzeichnis aufräumen
rm -rf "$TEMP_DIR"

# 7. Alte Backups löschen (Rotation)
log "Lösche alte Backups..."

# Täglich: Behalte letzte 7 Tage
find "$BACKUP_DIR" -name "paperless_backup_*.tar.gz" -type f -mtime +$RETENTION_DAYS -delete

# Optional: Wöchentliche Backups behalten
# Hier könnte man zusätzliche Logik einbauen für wöchentliche/monatliche Backups

log "Alte Backups bereinigt"

# 8. Optional: Offsite-Backup
if [ "$OFFSITE_ENABLED" = true ]; then
    log "Starte Offsite-Backup..."
    
    mkdir -p "$OFFSITE_DEST"
    
    # Beispiel mit rsync (anpassen je nach Setup)
    rsync -avz --delete "$BACKUP_DIR/" "$OFFSITE_DEST/"
    
    # Alternativ mit rclone (z.B. für Cloud-Storage):
    # rclone sync "$BACKUP_DIR" "remote:paperless-backups"
    
    if [ $? -eq 0 ]; then
        log "Offsite-Backup erfolgreich"
    else
        log "WARNUNG: Offsite-Backup fehlgeschlagen!"
    fi
fi

# Backup-Statistik
BACKUP_COUNT=$(ls -1 "$BACKUP_DIR"/paperless_backup_*.tar.gz 2>/dev/null | wc -l)
log "Anzahl vorhandener Backups: $BACKUP_COUNT"

log "=== Backup abgeschlossen ==="

# Optional: Benachrichtigung senden (z.B. via ntfy, gotify, email, etc.)
# curl -d "Paperless Backup erfolgreich: $BACKUP_SIZE" ntfy.sh/mein-paperless-backup
Code-Sprache: PHP (php)

Der Cron-Job

Um das Backup automatisch laufen zu lassen, richte ich einen Cron-Job ein:

# Crontab bearbeiten
sudo crontab -e
Code-Sprache: PHP (php)

Eintrag für tägliches Backup um 3 Uhr nachts:

# Paperless-NGX Backup - täglich um 3:00 Uhr
0 3 * * * /opt/paperless-ngx/scripts/backup.sh >> /mnt/backups/paperless/backup.log 2>&1
Code-Sprache: PHP (php)

Alternative Cron-Schedules

# Alle 6 Stunden
0 */6 * * * /opt/paperless-ngx/scripts/backup.sh

# Jeden Sonntag um 2 Uhr (wöchentlich)
0 2 * * 0 /opt/paperless-ngx/scripts/backup.sh

# Werktags um 1 Uhr nachts
0 1 * * 1-5 /opt/paperless-ngx/scripts/backup.sh
Code-Sprache: PHP (php)

Installation & Setup

1. Script vorbereiten

# Verzeichnis für Scripts erstellen
sudo mkdir -p /opt/paperless-ngx/scripts

# Script erstellen
sudo nano /opt/paperless-ngx/scripts/backup.sh

# Script ausfü
Code-Sprache: PHP (php)

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre, wie deine Kommentardaten verarbeitet werden.