Paperless NGX ist eine einfach zu bedienende Lösung zur Verwaltung von Dokumenten. Es kann PDF-Dateien, Office-Dokumente, Bilddateien und Mails verarbeiten.
Zunächst wird eine Docker-Laufzeitumgebung benötigt. Ubuntu bringt eine Docker-Umgebung mit. Allerdings funktioniert diese mitgelieferte Umgebung oftmals und hier konkret mit den Paperless-Paketen nicht. Darum ist eine Installation von Docker auf der Grundlage der Docker-Dokumentation zuverlässiger (s. https://docs.docker.com/engine/install/ubuntu/). Das habe ich in dem Beitrag über Docker beschrieben.
Wenn ich mich auf der SSH-Konsole des Servers angemeldet habe, dann bewege ich mich im Homeshare des angegebenen Users (also z.B. /home/andreas/). Hier erstelle ich einen Ordner paperless-nxg und wechsele dort hinein mit
mkdir paperless-nxg && cd paperless-ngx
Für Paperless NGX muss hier nun nur eine Datei docker-compose.yml angelegt werden mit
nano docker-compose.yml
mit folgendem Inhalt:
services:
broker:
image: docker.io/library/redis:8.4
restart: unless-stopped
volumes:
- redisdata:/data
db:
image: postgres:alpine
restart: unless-stopped
volumes:
- ./db:/var/lib/postgresql/data
environment:
POSTGRES_DB: paperless
POSTGRES_USER: paperless
POSTGRES_PASSWORD: paperless
webserver:
image: ghcr.io/paperless-ngx/paperless-ngx:2.19.1
restart: unless-stopped
depends_on:
- db
- broker
- gotenberg
- tika
ports:
- "8000:8000"
volumes:
- ./data:/usr/src/paperless/data
- ./media:/usr/src/paperless/media
- ./export:/usr/src/paperless/export
- ./consume:/usr/src/paperless/consume
environment:
PAPERLESS_URL: {Domain oder leer lassen}
PAPERLESS_TIME_ZONE: 'Europe/Berlin'
PAPERLESS_OCR_LANGUAGE: deu+eng
PAPERLESS_SECRET_KEY: 'echt komplexes, geheimes passwort wie z.B. 123456'
PAPERLESS_REDIS: redis://broker:6379
PAPERLESS_DBHOST: db
PAPERLESS_DBNAME: paperless
PAPERLESS_DBUSER: paperless
PAPERLESS_DBPASS: paperless
PAPERLESS_TIKA_ENABLED: 1
PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000
PAPERLESS_TIKA_ENDPOINT: http://tika:9998
gotenberg:
image: docker.io/gotenberg/gotenberg:8.24
restart: unless-stopped
# Beim Konvertieren von .eml-Files mit Gotenberg soll
# externer content wie z.B: tracking pixels oder javascript
# nicht mit konvertiert werden
command:
- "gotenberg"
- "--chromium-disable-javascript=true"
- "--chromium-allow-list=file:///tmp/.*"
tika:
image: docker.io/apache/tika:latest
restart: unless-stopped
volumes:
redisdata:
Hier wird zunächst Redis, die In-Memory-Komponente zur Beschleunigung der Datenbankzugriffe, definiert. Redis bekommt hier ein Volume data unter dem Namen redisdata im aktuellen Pfad zugewiesen. Dann wird die Datenbank postgres in der Version alpine mit dem persistenten Volume data definiert. Die Volume-Definition ist wichtig, damit nach einem Neustart des Servers bzw. Containers die Daten noch vorhanden sind. Die Credentials für die Datenbank werden in den Environment-Variablen für die Services db und webserver (natürlich identisch) definiert. Dann werden die Services tika und gotenberg definiert, damit Paperless-NGX Office-Formate und eMails verarbeiten kann. Hier ist im Service eine kleine Besonderheit eingebaut: Es werden chromium-Features genutzt, um Java-Script, Tracking-Pixel und andere unerwünschte externe Links auszuschließen. Die Restart-Policy "unless-stopped" sorgt dafür, dass die Container nach einem Reboot des Servers wieder gestartet werden, es sei denn, sie wurden vorher ausdrücklich gestoppt.
Paperless-NGX kann ich nun starten mit
docker compose up -d
Das System startet, was eine Weile dauert. Den Erfolg kann ich zwischendurch mit
docker ps
oder ausführlicher mit
docker logs paperless-nxg-webserver-1
ansehen. Wenn keine Fehler aufgetreten sind, dann sollte Paperless NGX starten und unter der eingetragenen Domain, so sie denn erreichbar ist oder unter der IP-Adresse des Servers mit der Portnummer 8000 angesprochen werden können.
Damit direkt in das DMS gescannt werden kann, muss der Scanner Dateien im Consume-Ordner ablegen können. Wenn dazu das SMB-Protokoll genutzt werden soll, dann ist auf dem DMS-Server ein Samba-Server zu installieren und eine entsprechende Freigabe einzurichen. Die Freigabe wird in der Datei "/etc/samba/smb.conf" eingetragen:
[paperless]
comment = Paperless Eingangsordner
path = /home/andreas/paperless-ngx/paperless-ngx/consume
browsable = yes
read only = no
guest ok = no
Nach jeder Änderung der smb.conf ist der Samba-Server neu zu starten:
sudo systemctl daemon-reload && sudo systemctl restart smbd
Nun ist der Consume-Ordner als Freigabe im Netz verfügbar. Verarbeitbare Dateien (Office-Dateien, Mails, Textdateien, Grafiken und natürlich PDF), die in diesen Ordner geschrieben werden, werden von Paperless-NGX verarbeitet.
Mein DMS-Server, ein LXC auf einem Proxmox-Host, wird jede Nacht auf den Proxmox-Backup-Server gesichert und kann komplett zurück gesichert werden und es kann auch ein Filerestore vorgenommen werden. Da für den PBS eine Retentionregel nach dem Grandfather-Father-Son-Prinzip eingerichtet ist, kann jederzeit auf die Stände der letzten Tage und Wochen zurück gesichert werden. Zu dieser Retention-Regel habe ich in meinem Youtube-Video (s. hier: Video) einiges erklärt.
Zur Offsite-Sicherung wird jeden Tag um 11:30 Uhr ein Export der Daten angestoßen und diese exportierten Daten dann um 12:00 Uhr verschlüsselt und inkrementell per duplicati auf einen entfernten Server übertragen. Ich habe duplicati in meiner Umgebung auf einem anderen Server installiert als den Paperless-NGX-Server. Darum muss ich dafür sorgen, dass dubplicati auf die Sicherungsdaten zugreifen kann (s.u.).
Das Exportverzeichnis ist ja mittels der oben aufgeführten docker-compose.yml persistent eingerichtet. Hier hinein werden per cronjob und exporter die Export-Dateien abgelegt werden. Dazu richte ich den Cronjob mit
sudo nano /etc/crontab
ein und ergänze die Systemdatei um folgenden Eintrag:
30 11 * * * andreas docker exec paperless-webserver-1 document_exporter /usr/src/paperless/data/export
So wird jeden Tag um 11:30 Uhr ein Export angestoßen. Der Exporter legt dabei alle Dokumente im Ursprungsformat, ihre jeweiligen PDF-Repräsentationen und Webvorschaubilder, eine Datei namens manifest.json mit allen Metadaten sowie eine Datei metadata.json mit der Angabe der Versionsnummer von Paperless-NGX in dem angegebenen Verzeichnis ab.
iDieses Verzeichnis ist per Samba freigegeben. Dazu steht in der Datei "/etc/samba/smb.conf" des DMS-Servers:
[export]
comment = Export von Paperless-NGX
path = /home/andreas/paperless-ngx/paperless-ngx/data/export
browsable = yes
read only = no
guest ok = no
Dieses Verzeichnis ist auf dem Server, auf dem Duplicati läuft, unter "/export" gemounted:
//10.10.0.110/export /export cifs vers=3.0,username=ichhalt,password=**********,uid=1000,gid=1000 0 0
In der Datei "docker-compose.yml" für Ducati ist dieses Verzeichnis als Volume eingetragen:
volumes:
...
- /export:/dms-export
In Duplicati ist nun ein Sicherungsjob namens "dms",
eingerichtet, der die Daten täglich um 12:00 Uhr incrementell
und verschlüsselt in das Verzeichnis "/backup/dms" sichert. Das
Verzeichnis "backup" ist in der Datei "docker-compose.yml" als
Volume mit dem Ziel "/remote-backup" eingetragen.
Das Verzeichnis "/remote-backup" auf dem Duplicati-Server ist
eine SMB-Freigabe auf einen vServer von Netcup, auf den per
Wireguard-Tunnel zugegriffen wird, und die auf dem
Duplicati-Server gemounted ist.
Die nachfolgende Grafik veranschaulicht das Prinzip (hoffentlich):

Der Zugriff auf die Anwendung kann abgesichert werden, indem mittels Nginx Proxy Manager HTTPS-Zugriffe ermöglicht (und erzwungen) werden. Außerdem kann eine Zwei-Faktor-Authentifizierung mit Authelia oder Authentik realisiert werden. Wenn die Anwendung über das Internet zugänglich ist, dann sollte das auf jeden Fall gemacht werden.
Updates können bequem durch Aktualisierung Container durchgeführt werden. Dazu wechselt man zunächst auf der Linux-Konsole in den Ordner mit der entsprechenden YAML-Datei (docker-compose.yml).
cd /home/andreas/paperless-ngx
Dort setzt man den Befehl zum Stoppen des Containers ab:
docker-compose down
Dann pullt man die aktuelle Version:
docker-compose pull
Das funktioniert, wenn wir bei der Installation die Version "latest" vorgegeben haben. Danach muss die neue Version gestartet werden:
docker-compose up -d
Wenn das ohne Fehlermeldungen durchgelaufen ist, dann ist die Paperless NGX-Instanz aktualisiert.
Für eine Migration oder einen Umzug müssen zunächst die Quell- und die Zielinstanz in der selben Version vorliegen. Ggf. ist zunächst ein Update durchzuführen. Dann wird von der Quellinstanz der Export durchgeführt:
docker exec -it paperless-webserver-1 document_exporter ../data/export
Die Daten liegen dann im Verzeichnis ../data/export (also z.B. "/home/andreas/paperless-ngx/data/export").
Zum Importieren müssen sie zunächst auf den Zielserver übertragen werden. Wenn sie in den oben genannten Ordner kopiert wurden, dann können sie nun mit dem Befehl
docker exec -it paperless-webserver-1 document_importer ../data/export
importiert werden. Dadurch wird die Datenbank überschrieben und alle Daten werden importiert. Der Name des betreffenden Containers (hier "paperless-webserver-1" genannt) muss natürlich passen. Er kann mit
docker ps
ausgelesen werden.
Wenn der Webserver nach einem Neustart des Servers nicht auf Port 8000 lauscht, dann hilft es, zunächst die Firewall des Server temporär zu deaktivieren und den Webserver neu zu starten. Danach kann die Firewall wieder aktiviert werden.