Deployn

Paperless-ngx: PostgreSQL auf Version 18 aktualisieren

Paperless-ngx mit Docker auf PostgreSQL 18 umstellen, zum Beispiel von Version 13 oder 14: Dump erstellen, Datenpfad anpassen, Daten zurückspielen und danach auf Paperless 3 updaten.

Veröffentlicht am
Paperless-ngx: PostgreSQL auf Version 18 aktualisieren hero image
Inhalt
Getestet mit
Paperless-ngx 3.4.2PostgreSQL 18.6Docker 29.9Ubuntu 24.04
Zuletzt geprüft am

Läuft dein Paperless-ngx schon seit Jahren, steckt darunter vermutlich noch die PostgreSQL-Version aus der damaligen Anleitung. PostgreSQL 13 bekommt seit November 2025 keine Sicherheitsupdates mehr, bei Version 14 endet der Support im November 2026. Neuere Paperless-Versionen verlangen außerdem eine neuere Datenbank, und genau daran scheitern viele Updates.

In dieser Anleitung stelle ich eine bestehende Paperless-Installation mit Docker Compose auf PostgreSQL 18 um. Das geht nicht, indem du nur die Versionsnummer im Image änderst. Eine neue Hauptversion kann die Datendateien der alten nicht lesen. Deshalb sichern wir die Datenbank als Dump und spielen sie in eine frische Datenbank zurück. Die Dokumente selbst bleiben dabei unberührt.

Der Weg funktioniert für jede alte Version. Ich habe ihn mit PostgreSQL 13 und mit PostgreSQL 14 durchgeführt, jeweils mit 30 Dokumenten, Tags, Korrespondenten und einem angemeldeten Benutzer.

Reihenfolge: erst die Datenbank, dann Paperless

Zwei Regeln bestimmen, in welcher Reihenfolge du vorgehst:

  • Neuere Paperless-Versionen brauchen PostgreSQL 14 oder neuer. Mit 2.17.1 lief Paperless noch auf PostgreSQL 13, zeigte aber die Warnung PostgreSQL 13 is deprecated and will not be supported in a future Paperless-ngx release. Die Versionen 2.18.4, 2.19.6, 2.20.0, 2.20.15 und 3.4.2 brachen beim Start mit PostgreSQL 14 or later is required (found 13.23) ab.
  • Paperless 3 lässt sich nur von Version 2.20.15 aus installieren. Ein direkter Sprung von einer älteren Version bricht mit Upgrading to v3 can only be performed from v2.20.15 ab.

Steckst du noch auf Paperless 2.17 oder älter mit PostgreSQL 13, ist der Ablauf deshalb:

  1. Datenbank auf PostgreSQL 18 umstellen (diese Anleitung).
  2. Paperless auf 2.20.15 aktualisieren und starten lassen, damit die Datenbankmigrationen laufen.
  3. Danach auf Paperless 3 aktualisieren.

Läuft bei dir schon Paperless 2.20.15 oder neuer, brauchst du nur den ersten Schritt.

Vorbereitung

Ich gehe von diesem Aufbau aus, wie er in meinen anderen Paperless-Anleitungen steht: Die Compose-Datei hat die drei Dienste broker, db und webserver, die Datenbank liegt als Ordner ./db neben der Compose-Datei. Heißt dein Datenbankdienst anders oder weichen Benutzer und Datenbankname ab, trägst du das gleich in Variablen ein.

Eigene Werte eintragen

Oben im Artikel kannst du vier Werte eintragen: den Namen des Datenbankdienstes, Benutzer und Datenbankname sowie die alte PostgreSQL-Version. Danach stehen deine Werte in allen Befehlen. Du findest sie in deiner Compose-Datei unter POSTGRES_USER und POSTGRES_DB. Die alte Version steckt nur in den Dateinamen.

Welche Version läuft aktuell?

Terminalbash
docker compose exec {{db_service}} postgres --version
postgres (PostgreSQL) 13.23 (Debian 13.23-1.pgdg13+1)

Backup anlegen

Ein Dump ist die Grundlage für den Umzug, aber noch kein vollständiges Backup. Sichere vor dem Start auch die Ordner media und data sowie den Ordner db. Wie das sauber geht, steht in Paperless-ngx Backup & Restore.

Zahlen notieren

Notiere dir vorher, was in der Datenbank steckt. Nach dem Umzug prüfst du damit, ob alles angekommen ist:

Terminalbash
docker compose exec -T {{db_service}} psql -U {{db_user}} -d {{db_name}} -Atc \
  "select 'documents',count(*) from documents_document union all
   select 'tags',count(*) from documents_tag union all
   select 'correspondents',count(*) from documents_correspondent union all
   select 'doctypes',count(*) from documents_documenttype union all
   select 'users',count(*) from auth_user"
documents|30
tags|5
correspondents|6
doctypes|6
users|3

Die Benutzer sind nicht nur deine eigenen. Paperless legt selbst zwei weitere an, deshalb steht hier eine 3 bei einem einzigen Konto.

Zusätzlich lohnt sich ein Blick auf das Dashboard, damit du die Zahlen auch dort vergleichen kannst.

Paperless-Dashboard vor dem Upgrade

Dump erstellen

Halte zuerst den Webserver an, damit während des Dumps nichts in die Datenbank geschrieben wird. Die Datenbank selbst muss weiterlaufen:

Terminalbash
docker compose stop webserver

Dann erzeugst du den Dump. Der Schalter -T ist wichtig, weil die Ausgabe in eine Datei umgeleitet wird:

Terminalbash
docker compose exec -T {{db_service}} pg_dump -U {{db_user}} -d {{db_name}} > dump_pg{{old_version}}.sql
ls -lh dump_pg{{old_version}}.sql
-rw-r--r-- 1 root root 316K Nov  4 20:50 dump_pg13.sql

Der Dump enthält alle Metadaten, den erkannten Text, Tags, Benutzer und Einstellungen, aber nicht die Dokumentdateien. Diese liegen im Ordner media. Deshalb ist die Datei bei 30 Dokumenten nur 316 KB groß. Der Dateiname enthält deine alte Version, dann weißt du später, woher der Dump stammt.

Neue Datenbank mit PostgreSQL 18 anlegen

Stoppe jetzt alle Container und verschiebe den alten Datenordner. Aus dem alten Ordner wird die Rückfallebene, und db ist wieder leer:

Terminalbash
docker compose down
mv db db_pg{{old_version}}_backup
mkdir db

Passe danach in der docker-compose.yml zwei Dinge an: das Image und den Pfad des Volumes.

yaml
db:
    image: postgres:{{old_version}}
    image: postgres:18
    volumes:
        - ./db:/var/lib/postgresql/data
        - ./db:/var/lib/postgresql

Die Zugangsdaten unter environment (POSTGRES_DB, POSTGRES_USER, POSTGRES_PASSWORD) lässt du genau so, wie sie waren. Sie müssen zu PAPERLESS_DBUSER und PAPERLESS_DBPASS beim Webserver passen. Die neue Datenbank wird beim ersten Start mit diesen Werten angelegt.

Der Datenpfad ist neu

Die Images ab PostgreSQL 18 speichern ihre Daten nicht mehr direkt im Ordner /var/lib/postgresql/data, sondern in einem Unterordner mit der Versionsnummer. Dafür muss das Volume eine Ebene höher eingebunden werden, auf /var/lib/postgresql. Lässt du den alten Pfad stehen, startet der Container gar nicht erst. Der Container startet dann immer wieder neu, und im Log steht:

Terminalbash
docker compose logs {{db_service}}
paperless-db  | Error: in 18+, these Docker images are configured to store database data in a
paperless-db  |        format which is compatible with "pg_ctlcluster" (specifically, using
paperless-db  |        major-version-specific directory names).
...
paperless-db  |        The suggested container configuration for 18+ is to place a single mount
paperless-db  |        at /var/lib/postgresql which will then place PostgreSQL data in a
paperless-db  |        subdirectory

Starte nur die Datenbank und prüfe, ob sie läuft:

Terminalbash
docker compose up -d {{db_service}}
docker compose exec {{db_service}} psql -U {{db_user}} -d {{db_name}} -Atc 'select version()'
ls db db/18
PostgreSQL 18.6 (Debian 18.6-1.pgdg13+2) on x86_64-pc-linux-gnu, compiled by gcc (Debian 14.2.0-19) 14.2.0, 64-bit
db:
18

db/18:
docker

Die Daten liegen jetzt unter db/18/docker. Die Datenbank ist noch leer.

Dump zurückspielen

Spiele den Dump ein. ON_ERROR_STOP=1 sorgt dafür, dass der Vorgang beim ersten Fehler abbricht und nicht halb fertig weiterläuft:

Terminalbash
docker compose exec -T {{db_service}} psql -U {{db_user}} -d {{db_name}} -v ON_ERROR_STOP=1 < dump_pg{{old_version}}.sql

Die Ausgabe ist eine lange Liste von SQL-Befehlen, die jeweils mit CREATE TABLE, COPY, ALTER TABLE oder ähnlichem quittiert werden. Fehlermeldungen darf es nicht geben. Bei meinen 30 Dokumenten ging das schnell.

Wiederhole jetzt die Abfrage von vorhin. Die Zahlen müssen identisch sein:

documents|30
tags|5
correspondents|6
doctypes|6
users|3

Paperless starten und prüfen

Starte alle Container:

Terminalbash
docker compose up -d
docker compose ps --format 'table {{.Name}}\t{{.Image}}\t{{.Status}}'
NAME              IMAGE                                        STATUS
paperless-db      postgres:18                                  Up 8 minutes
paperless-redis   redis:7                                      Up 7 minutes
paperless-web     ghcr.io/paperless-ngx/paperless-ngx:2.17.1   Up 27 seconds (health: starting)

Der Webserver braucht einen Moment, bis er healthy meldet. Im Log siehst du, dass er sich mit der neuen Datenbank verbindet:

Terminalbash
docker compose logs webserver | grep -i postgres
paperless-web  | [init-db-wait] Waiting for postgresql to report ready
paperless-web  | Connected to PostgreSQL

Die Warnung PostgreSQL 13 is deprecated ist verschwunden. Im Browser zeigt das Dashboard dieselben Zahlen wie vorher. Der Login blieb in meinem Test sogar erhalten, weil Paperless die Sitzungen ebenfalls in der Datenbank speichert und sie im Dump steckten. Zusätzlich habe ich nach dem Wechsel ein neues PDF in den Ordner consume gelegt. Es wurde ganz normal importiert, die Datenbank nimmt also auch neue Einträge an.

Paperless auf Version 3 aktualisieren

Läuft bei dir noch eine ältere Paperless-Version, folgt jetzt der zweite Teil. Direkt auf latest zu springen, funktioniert nicht. Mein Test mit 2.17.1 auf latest endete so:

paperless-web  | [ERROR] [paperless.checks] V3 upgrade check failed: last applied documents migration is '1068_alter_document_created'. Expected '1075_workflowaction_order' (v2.20.15). Ensure you have upgraded to v2.20.15 and run 'manage.py migrate' before upgrading to v3.
paperless-web  | ?: (paperless.E002) Cannot upgrade to Paperless-ngx v3 from this version.

Gehe deshalb in zwei Schritten vor. Ändere zuerst den Tag des Webserver-Images auf 2.20.15 und starte neu:

yaml
webserver:
    image: ghcr.io/paperless-ngx/paperless-ngx:2.17.1
    image: ghcr.io/paperless-ngx/paperless-ngx:2.20.15
Terminalbash
docker compose up -d
docker compose logs webserver | grep Applying
paperless-web  |   Applying documents.1073_migrate_workflow_title_jinja... OK
paperless-web  |   Applying documents.1074_workflowrun_deleted_at_workflowrun_restored_at_and_more... OK
paperless-web  |   Applying documents.1075_workflowaction_order... OK

Wenn die letzte Migration 1075_workflowaction_order durchgelaufen ist und der Container healthy meldet, setzt du den Tag beispielsweise auf 3.4.2 und startest erneut:

Terminalbash
docker compose up -d
docker compose ps --format 'table {{.Name}}\t{{.Image}}\t{{.Status}}'
NAME              IMAGE                                        STATUS
paperless-db      postgres:18                                  Up 10 minutes
paperless-redis   redis:7                                      Up 9 minutes
paperless-web     ghcr.io/paperless-ngx/paperless-ngx:3.4.2    Up 37 seconds (healthy)

Paperless-Dashboard nach dem Upgrade auf PostgreSQL 18 und Paperless 3.4.2

Aufräumen

Lass die Sicherungen ein paar Tage liegen und arbeite normal mit Paperless. Läuft alles stabil, kannst du sie löschen:

Terminalbash
rm -r db_pg{{old_version}}_backup
rm dump_pg{{old_version}}.sql

Wenn etwas schiefgeht

  • Der Datenbank-Container startet immer wieder neu: Prüfe den Pfad des Volumes. Er muss /var/lib/postgresql lauten, nicht /var/lib/postgresql/data.
  • PostgreSQL 14 or later is required: Dein Webserver ist neuer als die Datenbank. Stelle die Datenbank um, wie oben beschrieben.
  • Cannot upgrade to Paperless-ngx v3 from this version: Gehe erst auf 2.20.15, lass die Migrationen laufen und aktualisiere dann auf 3.
  • Zurück zum alten Stand: Stoppe alles, lösche den neuen Ordner db, benenne db_pg<VariableSpan name="old_version">13</VariableSpan>_backup wieder in db um und setze in der Compose-Datei Image und Volume-Pfad auf die alten Werte. Das habe ich nicht getestet.

Fazit

Der Wechsel auf PostgreSQL 18 ist mit einem Dump schnell erledigt, wenn du an drei Dinge denkst: den neuen Datenpfad /var/lib/postgresql, die unveränderten Zugangsdaten und die Reihenfolge erst Datenbank, dann Paperless über 2.20.15 auf Version 3. Bleibt der alte Datenordner liegen, riskierst du nichts.

FAQ

Häufige Fragen

Kann ich bei Paperless-ngx einfach die PostgreSQL-Version im Image hochsetzen?

Nein. Eine neue PostgreSQL-Hauptversion kann die Datendateien der alten nicht lesen, der Container startet dann nicht oder bricht ab. Du sicherst die Datenbank mit pg_dump und spielst sie in eine frische Datenbank der neuen Version zurück.

Warum ändert sich bei PostgreSQL 18 der Datenpfad?

Die Docker-Images ab PostgreSQL 18 legen die Daten in einem Unterordner mit der Versionsnummer ab, zum Beispiel /var/lib/postgresql/18/docker. Das Volume muss deshalb auf /var/lib/postgresql zeigen und nicht mehr auf /var/lib/postgresql/data.

Gehen beim Umzug meine Dokumente verloren?

Nein. Die Dokumentdateien liegen im Ordner media, den der Dump nicht berührt. Der Dump enthält nur die Datenbank mit Metadaten, erkanntem Text, Tags, Benutzern und Einstellungen. Den alten Datenbankordner verschiebst du nur und löschst ihn erst, wenn alles stabil läuft.

Funktioniert die Anleitung auch mit PostgreSQL 14 oder anderen Versionen?

Ja. Du trägst oben deine alte Hauptversion ein. Getestet habe ich PostgreSQL 13 und 14. PostgreSQL 15, 16 und 17 habe ich nicht selbst durchgespielt, der Ablauf mit pg_dump ist aber derselbe.

In welcher Reihenfolge aktualisiere ich Datenbank und Paperless?

Zuerst die Datenbank auf PostgreSQL 18, danach Paperless auf 2.20.15 und erst dann auf Version 3. Paperless 3 lässt sich nur von 2.20.15 aus installieren, und neuere Paperless-Versionen verlangen mindestens PostgreSQL 14.

Wie komme ich zurück, wenn etwas schiefgeht?

Stoppe die Container, lösche den neuen Ordner db, benenne den gesicherten Ordner wieder in db um und setze Image und Volume-Pfad in der Compose-Datei auf die alten Werte. Diesen Rückweg habe ich nicht getestet, deshalb gehört vorher ein vollständiges Backup dazu.