Paperless-ngx-Datenbankmigration: Stabile Archive sicher übertragen

Paperless-ngx-Datenbankmigration: Praxisführer für stabile Dokumentenarchive

Sie kennen das: Irgendwann beißt jeder produktive Paperless-ngx-Stack in die Wachstumstabelle. Die SQLite-Datei, die anfangs so bequem murmelte, stöhnt unter Last. Oder der PostgreSQL-Server braucht ein Hardware-Upgrade, einen Cloud-Umzug oder ein Datenbank-Schema-Update. Dann steht die ungeliebte Königsdisziplin an: Die Migration der Dokumentendatenbank – bei laufendem Betrieb und ohne Datenverlust. Keine Sorge, das ist machbar. Wenn man weiß, wo die Fallstricke liegen.

Warum Migration mehr ist als Copy-Paste

Paperless-ngx speichert Metadaten in relationalen Strukturen: Dokumententypen, Tags, Korrespondenten, aber auch die Beziehungen zwischen Dokumenten und deren Inhalten im Volltextindex. Ein simples Datenbank-Dump-Restore verhält sich hier wie ein Umzug, bei dem Kisten wild durchgeschüttelt werden. Die Konsistenz bricht. Dokumente verschwinden aus Ordnern, Suchindexe liegen daneben. Wir brauchen einen kontrollierten Transfer.

Der klassische Fall: SQLite zu PostgreSQL

Der häufigste Migrationspfad. SQLite eignet sich für Testinstanzen oder kleine Archive – aber bei 50.000+ Dokumenten oder Parallelzugriffen wird‘s eng. PostgreSQL hingegen skaliert, bietet Backup-Routinen und Replikation. Die Migration erfolgt in drei Kernschritten:

  1. Vorbereitung ist alles:
    • Paperless-ngx stoppen (docker-compose down)
    • SQLite-Datenbank sichern (cp document_consumer.sqlite document_consumer.sqlite.bak)
    • PostgreSQL-Container in der docker-compose.yml konfigurieren (externe Volumes nicht vergessen!)
    • Environment-Variablen anpassen (PAPERLESS_DBHOST, PAPERLESS_DBUSER etc.)
  2. Datenübertragung mit pgloader:

    Das Open-Source-Tool pgloader wandelt SQLite-Schemata automatisch in PostgreSQL-kompatible Strukturen. Kritisch ist die Behandlung von Fulltext-Search und Datumswerten. Ein Minimal-Kommando:

    pgloader document_consumer.sqlite postgresql://paperless:passwort@dbhost:5432/paperless

    Achtung: Ohne Schema-Validierung geht das schief. Prüfen Sie Logs auf Datentyp-Warnungen (text vs varchar).

  3. Post-Migration-Check:
    • Dokumentenzahl prüfen (SELECT COUNT(*) FROM documents_document;)
    • Beziehungen testen (Hat Dokument #1234 noch seine Tags?)
    • Volltextsuche verifizieren (Suchbegriff aus PDF-Inhalt probieren)

PostgreSQL zu PostgreSQL: Wenn der Server wechselt

Cloud-Migration, Hardware-Update oder Replikationseinrichtung – auch PostgreSQL-Instanzen müssen wandern. Hier ist pg_dump und pg_restore die Waffe der Wahl. Aber Vorsicht bei großen Archiven:

# Auf Quellserver:
pg_dump -Fc -U paperless paperless > paperless.dump

# Auf Zielserver:
pg_restore -d paperless -U paperless --clean --create paperless.dump

Der -Fc-Parameter (Custom Format) beschleunigt Transfer und Restore. Wichtig: --clean löscht vorhandene Daten in der Zieldatenbank – also nur auf leere Zieldatenbanken anwenden! Bei laufendem Betrieb nutzen Sie pg_basebackup oder replizieren via Logical Replication.

Die Achillesferse: Volltextindex konservieren

Paperless-ngx nutzt PostgreSQLs tsvector für schnelle Suchläufe. Diese Indizes sind datenbankintern – ein Restore überträgt sie korrekt. Ausnahme: Wenn Sie Tesseract-OCR nutzen und Dokumente nach der Migration erneut indexiert werden, prüfen Sie die PAPERLESS_OCR_LANGUAGE Einstellung. Falsche Sprachen führen zu kaputten Indexierungen.

Schema-Updates: Wenn Paperless-ngx vorprescht

Neue Paperless-ngx-Versionen ändern manchmal das Datenbankschema. Django-Migrationen (manage.py migrate) erledigen das automatisch – aber nur, wenn die App startet. Problematisch wird‘s bei Major-Updates mit Breaking Changes. Hier hilft:

  • Vor Update: Datenbank-Backup (ja, wirklich!)
  • Paperless-ngx im neuen Container starten lassen – die Migration läuft automatisch
  • Critical: Bei Fehlern Container stoppen, Datenbank-Restore, Problem analysieren

Ein Praxis-Tipp: Testen Sie Schema-Updates immer zuerst in einer Staging-Umgebung mit Kopie der Produktivdaten. Nicht selten brechen Plugins oder Custom Scripts bei neuen Feldtypen.

Die unterschätzte Gefahr: Dateisystem-Pfade

Paperless-ngx speichert Dokumente im Dateisystem (meist /usr/src/paperless/data). Die Datenbank enthält relative Pfade zu diesen Dateien. Bei Serverumzügen wird das zur Falle:

# Dokumenten-Tabelle:
id | filename          | archive_filename
---|-------------------|------------------
42 | invoices/2024.pdf | archive/2024.pdf

Migrieren Sie nur die DB, nicht aber das data-Verzeichnis, fehlen plötzlich Dateien. Lösung: Entweder identisches Dateisystem-Layout auf dem Zielsystem herstellen – oder die Pfade in der DB anpassen. Letzteres ist riskant: Ein Update-Skript muss alle filename– und archive_filename-Einträge ändern. Besser: Symlinks oder Bind-Mounts nutzen, um alte Pfade verfügbar zu halten.

Notfallplan: Rollback-Strategien

Jede Migration braucht einen Rückfahrschein. Im Ernstfall müssen Sie in 15 Minuten wieder betriebsbereit sein. So geht‘s:

  1. Vor Migration: Vollständiges Backup von Datenbank und Dokumentenverzeichnis
  2. Dokumentierte Ausfallzeit: Nutzer informieren, Wartungsfenster kommunizieren
  3. Rollback-Test: Backup-Restore-Prozedur vor der Migration trocken durchspielen
  4. Fallback-Bereitstellung: Alte Server-Instanz nicht löschen, sondern nur stoppen

Ein interessanter Aspekt: Bei PostgreSQL-Migrationen können Sie während des Rollbacks oft einfach den alten Container wieder starten – sofern sich am Dateisystem nichts änderte. Das spart Zeit.

Automatisierung mit Ansible: Migration als Code

Wer regelmäßig migriert (etwa für Testumgebungen), scriptet den Prozess. Mit Ansible wird daraus reproduzierbarer Code:

- name: Paperless DB migrieren
  hosts: paperless_new
  tasks:
    - name: Alte DB stoppen
      command: docker-compose down
      delegate_to: paperless_old
    
    - name: SQLite-DB kopieren
      fetch:
        src: /opt/paperless/data/db.sqlite3
        dest: /tmp/db.sqlite3
    
    - name: PostgreSQL-Container starten
      command: docker-compose up -d db
    
    - name: pgloader installieren
      apt: 
        name: pgloader 
        state: present
    
    - name: Daten laden
      command: pgloader /tmp/db.sqlite3 postgresql://paperless:{{ db_pass }}@localhost/paperless

Solche Skripte reduzieren menschliche Fehler – vorausgesetzt, Sie testen sie intensiv.

Fazit: Migration als Routine statt Drama

Paperless-ngx-Datenbanken zu migrieren ist kein Hexenwerk. Es braucht Planung, saubere Backups und Respekt vor den Datenbeziehungen. Die goldenen Regeln? Erstens: Niemals ohne vollständiges Backup arbeiten. Zweitens: Immer zuerst in einer isolierten Umgebung testen. Drittens: Dateisystempfade nicht vergessen.

Mit wachsenden Dokumentenmengen wird Datenbankpflege zum Dauerjob. Wer früh auf PostgreSQL setzt und Migrationsskripte pflegt, spart sich später schlaflose Nächte. Denn im Idealfall merkt kein Nutzer, dass unter der Haube ein komplettes Archiv umgezogen ist – außer an der sprunghaft verbesserten Suchgeschwindigkeit.

Nicht zuletzt zeigt sich: Ein dokumentengetriebener Betrieb lebt von stabilen Archiven. Und die fangen bei der Datenbank an.