Da ich schon lange Paperless als digitales Dokumenten Archiv nutze, stellte sich immer wieder die Frage wie ziehe ich eigentlich die Datenbank auf eine neue Version von Postgres um.
Aber Halt, bevor Ihr Euch jetzt schon entsetzt abwendet weil Ihr kA habt wovon ich rede eine kurze Einleitung. Paperless ist wie schon erwähnt ein webbasierendes Dokumentenarchiv was ihr selbst bei Euch daheim oder bei einen Host im Internet aufsetzen könnt. Zum selber Hosten bietet sich die Nutzung von Docker an, denn so lassen sich die einzelnen Bestandteile die Paperless zum Starten benötigt einfacher konfigurieren. Der mit Paperless bei mir zu Grunde liegende Workflow basiert dabei auf einen Dokumenten Einzugsscanner mit (W)LAN Funktion, denn so lassen sich neue Dokumente direkt in den Eingangsordner von Paperless transportieren. Die Verarbeitung der neuen Dokumente erledigt dann Paperless über eigens erstellte Vorlagen oder manuell über die Webseite der installierten Instanz.
Eines der nötigen Zusatzpakete die Paperless benötigt ist Postgres, also eine schlanke auf SQL basierende Datenbank. Dort werden alle systemrelevante Daten von Paperless gespeichert. Zum Zeitpunkt der Erstellung ist die Release Version von Postgres v16 und Diese bietet noch einen weit in die Zukunft reichenden Support (Updates) an.
Bevor ich mich dem Thema des Umzugs der Daten auf diese Version annahm lief bei mir die Paperless Installation noch mit Postgres v13 (Support bis 2025). Es bestand also eigentlich kein Handlungsbedarf, aber da mich die Frage wie man das macht keine Ruhe gelassen hat, kam mir vor ein paar Tagen das Tutorial Video von @Navigio ganz Recht. In dem Video beschreibt er den Umzug der Datenbank auf einen Synology NAS innerhalb von Docker und Portainer. Dieses Vorgehen hat mich motiviert es auf meine Hardware/Software Situation zu portieren.
Ausgangssituation:
- Server mit Proxmox Virtualisierung
- auf Debian basierender LXC (Proxmox eigener Linux Container)
- installierte Docker, Docker-Compose Umgebung
- Paperless und alle nötigen Container (Postgres (v13), Redis7, Gotenberg, Tika laufen
- SSH Zugriff auf den LXC (entweder über die Proxmox Shell des LXC oder wenn sshd entsprechend eingerichtet über die Shellkonsole des PC
Ziel:
- Datenbank von älterer Postgres Version auf aktuele Version umziehen
Eines noch, die Ausgangssituation oben beschreibt meine Ausgangssituation und Diese muß NICHT Eure sein.
Wir beginnen mit dem bei der Erstinstallation verwendeten Compose Datei die üblicherweise im YAML Format vorliegt.
version: "3.4"
services:
broker:
image: docker.io/library/redis:7
container_name: broker
restart: unless-stopped
volumes:
- /data/paperless/redis/_data:/data
db:
image: docker.io/library/postgres:13
container_name: db
restart: unless-stopped
volumes:
- /data/paperless/postgresql/_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: paperless
POSTGRES_USER: paperless
POSTGRES_PASSWORD: paperless
webserver:
image: ghcr.io/paperless-ngx/paperless-ngx:latest
container_name: webserver
restart: unless-stopped
depends_on:
- db
- broker
- gotenberg
- tika
ports:
- 8001:8000
healthcheck:
test: ["CMD", "curl", "-fs", "-S", "--max-time", "2", "http://localhost:8000"]
interval: 30s
timeout: 10s
retries: 5
volumes:
- /data/paperless/consume:/usr/src/paperless/consume
- /data/paperless/data:/usr/src/paperless/data
environment:
PAPERLESS_ADMIN_USER: xxx
PAPERLESS_ADMIN_PASSWORD: xxx
PAPERLESS_REDIS: redis://broker:6379
PAPERLESS_DBHOST: db
PAPERLESS_TIKA_ENABLED: 1
PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000
PAPERLESS_TIKA_ENDPOINT: http://tika:9998
PAPERLESS_OCR_LANGUAGE: deu
PAPERLESS_TIME_ZONE: Europe/Berlin
USERMAP_UID: 1000
USERMAP_GID: 1000
gotenberg:
image: docker.io/gotenberg/gotenberg:latest
container_name: gotenberg
restart: unless-stopped
command:
- "gotenberg"
- "--chromium-disable-routes=true"
- "--chromium-allow-list=file:///tmp/.*"
tika:
image: ghcr.io/paperless-ngx/tika:latest
container_name: tika
restart: unless-stopped
Erläuterung:
- Host Pfad der Datenbank => /data/paperless/postgresql/_data
- Enviroment Datenbank Angaben (paperless) eventuell ändern (für mehr Sicherheit)
- Host Paperless Eingang Überwachungsordner => /data/paperless/consume
Wir beginnen mit einer Sicherungskopie des Installation Docker-Compose File
cp docker-compose.yml docker-compose-orig.yml
Dann editieren wir die docker-compose.yml und ergänzen den gezeigten Blockcode
nano docker-compose.yml
db:
image: docker.io/library/postgres:13
container_name: db
restart: unless-stopped
volumes:
- /data/paperless/postgresql/_data:/var/lib/postgresql/data
- /data/paperless/postgresql/backup:/backup
environment:
POSTGRES_DB: paperless
POSTGRES_USER: paperless
POSTGRES_PASSWORD: paperless
db-16:
image: docker.io/library/postgres:16
container_name: db-16
restart: unless-stopped
volumes:
- /data/paperless/postgresql/_data-16:/var/lib/postgresql/data
- /data/paperless/postgresql/backup:/backup
environment:
POSTGRES_DB: paperless
POSTGRES_USER: paperless
POSTGRES_PASSWORD: paperless
Es wird ein zweiter Container mit der neuen Postgres Version 16 gestartet und die Pfade angepasst. Darüber hinaus verlinken wir einen /backup Folder in beide Container, denn dort wird später der Datenbank Dump geschrieben. Dann Datei speichern (STRG+O) und nano verlassen (STRG+X). Nun fertige docker-compose.yml zur Sicherheit nochmal wegschreiben.
cp docker-compose.yml docker-compose-upgr.yml
Nun diese Änderungen übergeben und die neue Docker Konfiguration starten
docker compose up -d
Um einen gesicherten Datenbank Zustand herzustellen stoppen wir nun alle Container außer die beiden Datenbank (Postgres) Container. Um Diese stoppen zu können müssen wir die Container IDs ermitteln
docker ps
Dank dieser Übersicht können wir nun die genannten Container stoppen. Im Bild oben fehlt der alte Postgres Container! Bei Euch muss der auch gelistet sein.
docker stop c869ee47fc38 43da162bb5dd d9c50d670102 8fd18438a4a9
Wenn das ohne Fehler funktioniert hat listet Docker die gestoppten Container auf.
Nun müssen wir uns mit der Bash Shell in den Container begeben. Unten stehenden Code entsprechend anpassen und die ID des alten Postgres Container nutzen
docker exec -it ID-ALTE-POSTGRES bash
Nun in der Bash mit folgenden Befehl den Datenbank Dump auf den Host /backup Folder schreiben
pg_dumpall -U $POSTGRES_USER > /backup/<dateiname>
Dabei den Placeholder <dateiname> mit gewünschten Namen ergänzen z.B.
pg_dumpall -U $POSTGRES_USER > /backup/20231208.sql
Bei der Ausführung erfolgt keine Rückmeldung, nur eventuelle Fehler werden gemeldet. Überprüfen lässt sich die Aktion natürlich wie folgt
ls -la /backup/
Oder nach Verlassen der Container Bash (mit dem Befehl exit) auf dem Host
ls -la /data/paperless/postgresql/backup
skywatcher@pve-paperless:~$ ls -la /data/paperless/postgresql/backup
insgesamt 1324
drwxr-xr-x 2 root root 4096 8. Dez 21:37 .
drwxr-xr-x 5 skywatcher skywatcher 4096 8. Dez 21:30 ..
-rw-r--r-- 1 root root 1344228 8. Dez 21:37 20231208.sql
Nun stellen wir eine Verbindung zum neuen Postgres Container her
docker exec -it ID-NEUE-POSTGRES bash
Dort wird nun folgender Befehl eingeben. Dabei den Placeholder <dateiname< durch den Dump Namen der Datenbank ersetzen, also wie oben zu sehen z.B. /backup/20231209.sql
psql -d $POSTGRES_DB -U $POSTGRES_USER < /backup/<dateiname>
skywatcher@pve-paperless:~$ docker exec -it 33f202298ae5 bash
root@33f202298ae5:/# psql -d $POSTGRES_DB -U $POSTGRES_USER < /backup/20231209.sql
Nach Abschicken des Befehl laufen ganz viele Meldungen durch die Bash und das kann je nach Menge der Datenbankeinträge einen Moment dauern.
Nun editieren wir nochmal die docker-compose.yml und erstellen eine Version nachdem Upgrade der Datenbank.
nano docker-compose.yml
version: "3.4"
services:
broker:
image: docker.io/library/redis:7
container_name: broker
restart: unless-stopped
volumes:
- /data/paperless/redis/_data:/data
db-13:
image: docker.io/library/postgres:13
container_name: db-13
restart: unless-stopped
volumes:
- /data/paperless/postgresql/_data:/var/lib/postgresql/data
# - /data/paperless/postgresql/backup:/backup
environment:
POSTGRES_DB: paperless
POSTGRES_USER: paperless
POSTGRES_PASSWORD: paperless
POSTGRES_HOST_AUTH_METHOD: trust
db:
image: docker.io/library/postgres:16
container_name: db
restart: unless-stopped
volumes:
- /data/paperless/postgresql/_data-16:/var/lib/postgresql/data
# - /data/paperless/postgresql/backup:/backup
environment:
POSTGRES_DB: paperless
POSTGRES_USER: paperless
POSTGRES_PASSWORD: paperless
webserver:
image: ghcr.io/paperless-ngx/paperless-ngx:latest
container_name: webserver
restart: unless-stopped
depends_on:
- db
- broker
- gotenberg
- tika
ports:
- 8001:8000
healthcheck:
test: ["CMD", "curl", "-fs", "-S", "--max-time", "2", "http://localhost:8000"]
interval: 30s
timeout: 10s
retries: 5
volumes:
- /data/paperless/consume:/usr/src/paperless/consume
- /data/paperless/data:/usr/src/paperless/data
- /data/paperless/media:/usr/src/paperless/media
- /data/paperless/export:/usr/src/paperless/export
environment:
PAPERLESS_ADMIN_USER: xxx
PAPERLESS_ADMIN_PASSWORD: xxx
PAPERLESS_REDIS: redis://broker:6379
PAPERLESS_DBHOST: db
PAPERLESS_TIKA_ENABLED: 1
PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000
PAPERLESS_TIKA_ENDPOINT: http://tika:9998
PAPERLESS_OCR_LANGUAGE: deu
PAPERLESS_TIME_ZONE: Europe/Berlin
USERMAP_UID: 1000
USERMAP_GID: 1000
gotenberg:
image: docker.io/gotenberg/gotenberg:latest
container_name: gotenberg
restart: unless-stopped
command:
- "gotenberg"
- "--chromium-disable-routes=true"
- "--chromium-allow-list=file:///tmp/.*"
tika:
image: ghcr.io/paperless-ngx/tika:latest
container_name: tika
restart: unless-stopped
Was wurde geändert? Nun wir haben der alten Datenbank den Namen db-13 gegeben und er neuen Datenbank den Namen db (auf die Paperless auch zugreifen wird). Außerdem haben wir die backup Folder in beiden Datenbank Container auskommentiert da wir Diese nicht mehr benötigen. Nun können wir die Container neu bauen lassen und zum Test starten.
docker compose up -d
Wenn es ohne Fehler durchgelaufen ist prüfen wir trotzdem das Log des Paperless Webserver auf Fehler. Dazu zuerst die ID des Paperless Container ermitteln und dann die ID in den Befehl einfügen z.B.
docker ps
docker logs c869ee47fc38
Dort sollten keine Errors zu sehen sein. Nun können wir auch das Webif von Paperless mit der neuen Postgres bestaunen.
http://IP-ADRESSE-PAPERLESS:8001
https://10.3.2.104:8001 <= Beispiel
Schön und gut, allerdings sollten wir nochmal eingreifen und das Chaos etwas entschlacken. Dazu ändern wir nun Final noch einmal die docker-compose.yml
version: "3.4"
services:
broker:
image: docker.io/library/redis:7
container_name: broker
restart: unless-stopped
volumes:
- /data/paperless/redis/_data:/data
db:
image: docker.io/library/postgres:16
container_name: db
restart: unless-stopped
volumes:
- /data/paperless/postgresql/_data-16:/var/lib/postgresql/data
environment:
POSTGRES_DB: paperless
POSTGRES_USER: paperless
POSTGRES_PASSWORD: paperless
POSTGRES_HOST_AUTH_METHOD: trust
webserver:
image: ghcr.io/paperless-ngx/paperless-ngx:latest
container_name: webserver
restart: unless-stopped
depends_on:
- db
- broker
- gotenberg
- tika
ports:
- 8001:8000
healthcheck:
test: ["CMD", "curl", "-fs", "-S", "--max-time", "2", "http://localhost:8000"]
interval: 30s
timeout: 10s
retries: 5
volumes:
- /data/paperless/consume:/usr/src/paperless/consume
- /data/paperless/data:/usr/src/paperless/data
- /data/paperless/media:/usr/src/paperless/media
- /data/paperless/export:/usr/src/paperless/export
environment:
PAPERLESS_ADMIN_USER: xxx
PAPERLESS_ADMIN_PASSWORD: xxx
PAPERLESS_REDIS: redis://broker:6379
PAPERLESS_DBHOST: db
PAPERLESS_TIKA_ENABLED: 1
PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000
PAPERLESS_TIKA_ENDPOINT: http://tika:9998
PAPERLESS_OCR_LANGUAGE: deu
PAPERLESS_TIME_ZONE: Europe/Berlin
USERMAP_UID: 1000
USERMAP_GID: 1000
gotenberg:
image: docker.io/gotenberg/gotenberg:latest
container_name: gotenberg
restart: unless-stopped
command:
- "gotenberg"
- "--chromium-disable-routes=true"
- "--chromium-allow-list=file:///tmp/.*"
tika:
image: ghcr.io/paperless-ngx/tika:latest
container_name: tika
restart: unless-stopped
Der aufmerksame Leser wird erkennen das wir die alte Postgres und den Link des Backup Folder entfernt haben. Diesen Stand können wir nun auch für unsere Doku als docker-compose-final.yml sichern.
cp docker-compose.yml docker-compose-final.yml
Bevor wir die entschlackten Container starten empfiehlt es sich mal alle Container zu stoppen und dann neu zu starten.
docker stop $(docker ps -a -q)
docker compose up -d
Troubleshooting
Sollte beim Starten der Container eine Fehlermeldung erscheinen mit dem Inhalt ‚–remove-orphans‘ solltest für den betroffenen Container (vermutlich der alte Postgres Container) folgenden Befehl ausführen und dann die Container alle wieder neu erstellen und starten
docker-compose down --remove-orphans
docker compose up -d
weiterführende Publikationen
- vielen Dank an Jürgen vom Youtube Kanal @Navigio
- Anregung dieses Tutorial entstand durch dieses Video
- Paperless-ngx im LXC Container installieren von Lucas Schreiner alias ‚Schreiners IT‘
Entdecke mehr von Enigmawelt
Subscribe to get the latest posts sent to your email.