Unterstützung des Kanals
Hinweis: Der folgende Link ist ein Affiliate-Link.
Die Erstellung meiner Skripte und Videos ist mit einem erheblichen zeitlichen Aufwand verbunden – von der technischen Vorbereitung über intensive Recherche bis hin zu Tests, Aufnahmen und Nachbearbeitung. Alle Inhalte stelle ich dir dennoch vollständig kostenlos zur Verfügung.
Wenn du meine Arbeit unterstützen möchtest, kannst du das ganz einfach tun: Für deine Amazon-Bestellungen nutze gern meinen Partner-Link. Für dich ändert sich am Preis nichts – ich erhalte lediglich eine kleine Provision. Vielen Dank für deinen Support!
Jetzt über Amazon unterstützen👉 Direkt auf YouTube schauen und abonnieren:
Smart Home & more auf YouTube
📢 Update 27.10.2026: Paperless-ngx 3 ist da – und das ändert einiges!
Seit dem 24. Juli 2026 liefert das Docker-Image
latestdie Version 3. Paperless 3 braucht zwei neue Pflichtangaben in der docker-compose.yml und lässt sich nur von Version 2.20.15 aus aktualisieren. Wer einfachdocker compose pullausführt, bekommt einen Container, der nicht mehr startet.Neuinstallation: Das Skript install_paperless.sh ist angepasst und installiert Paperless 3.3.4. Einfach wie gewohnt verwenden.
Bestehende Installation: Bitte nicht von Hand
docker compose pullmachen. Nutzt das neue Skript upgrade_paperless_v3.sh, siehe Abschnitt „Upgrade von Paperless 2 auf Paperless 3“. Und vorher unbedingt ein Backup in Proxmox anlegen!
Erstveröffentlichung 14.02.2025, komplett überarbeitet und erweitert am 27.10.2026.
In diesem Video zeige ich euch, wie ihr unter Proxmox (LXC oder VM) oder auf einem separaten PC Paperless-ngx einrichtet. Da es dabei einiges zu beachten gibt, habe ich euch Skripte erstellt, die euch fast die gesamte Arbeit abnehmen:
- install_paperless.sh – Neuinstallation von Paperless-ngx 3
- upgrade_paperless_v3.sh – Upgrade einer bestehenden Installation von Paperless 2 auf 3 (neu seit 27.10.2026)
- backup.sh / restore.sh – Backup und Restore über Export und Import
- backup_new.sh / restore_new.sh – 1:1-Backup und Restore des kompletten Datenverzeichnisses
Möchtest du Paperless-ngx als Home Assistant Add-on installieren, findest du hier eine Anleitung dazu: https://youtu.be/wCiSkHQtYEE
Alle Skripte laden, ausführbar machen – und los geht’s:
cd /root wget https://smarthomeundmore.de/wp-content/uploads/install_paperless.sh wget https://smarthomeundmore.de/wp-content/uploads/upgrade_paperless_v3.sh wget https://smarthomeundmore.de/wp-content/uploads/backup.sh wget https://smarthomeundmore.de/wp-content/uploads/restore.sh wget https://smarthomeundmore.de/wp-content/uploads/backup_new.sh wget https://smarthomeundmore.de/wp-content/uploads/restore_new.sh chmod +x *.sh
🆕 Neuinstallation mit install_paperless.sh
Das Skript richtet auf einem frischen Ubuntu (LXC-Container oder VM) alles ein: Docker, den Benutzer paperless, die Samba-Freigaben consume, backup und restore, die docker-compose.yml und zum Schluss Paperless-ngx selbst mit Postgres 17, Redis 8, Gotenberg und Tika.
Voraussetzungen:
- Frisches Ubuntu 22.04, 24.04 oder 26.04. Bei einem LXC-Container unter Proxmox muss unter Options → Features die Option Nesting aktiviert sein, sonst läuft Docker nicht.
- Mindestens 2 CPU-Kerne, 4 GB RAM und 20 GB Festplatte. Für die Dokumente entsprechend mehr.
- Internetzugang, das Skript lädt Docker und die Images herunter.
Ablauf:
- Skript als root starten:
./install_paperless.sh - Das Skript fragt nach dem Passwort für den Linux-Benutzer
paperless(gleichzeitig das Samba-Passwort), dem Admin-Benutzernamen für Paperless (Standard: paperless) und dem Admin-Passwort. - Danach läuft alles automatisch. Je nach Internetanschluss dauert es fünf bis zehn Minuten.
- Am Ende steht die Adresse auf dem Bildschirm, z. B.
http://192.168.1.50:8001. Dort meldet ihr euch mit dem Admin-Benutzer an.
Hinweis (27.10.2026): Das Skript installiert jetzt Paperless-ngx 3.3.4. Die Version ist im Skript fest eingetragen (PAPERLESS_VERSION), damit ein späteres docker compose pull nicht ungefragt eine neue Hauptversion einspielt. Wer später aktualisieren will, setzt die Versionsnummer in der docker-compose.yml bewusst hoch. Gegenüber der Fassung vom November 2025 hat sich geändert:
PAPERLESS_SECRET_KEYwird beim Installieren erzeugt (seit Paperless 3.0 Pflicht)PAPERLESS_DBENGINE: postgresqlist eingetragen (seit Paperless 3.0 Pflicht)PAPERLESS_CONSUMER_BARCODE_SCANNERist entfernt, ZXing ist jetzt der einzige Barcode-ScannerPAPERLESS_DBSSLMODEwurde durchPAPERLESS_DB_OPTIONSersetzt- Die Besitzrechte der Postgres- und Redis-Verzeichnisse bleiben jetzt unangetastet. Der Neustart nach der Installation ist damit nicht mehr nötig.
Skript install_paperless.sh
#!/bin/bash
# install_paperless.sh - Stand 27.10.2026 - fuer Paperless-ngx 3.x
# Aenderungen gegenueber der Fassung vom 12.11.2025:
# - feste Paperless-Version statt "latest" (PAPERLESS_VERSION unten)
# - PAPERLESS_SECRET_KEY wird erzeugt (seit 3.0 Pflicht)
# - PAPERLESS_DBENGINE: postgresql (seit 3.0 Pflicht)
# - PAPERLESS_CONSUMER_BARCODE_SCANNER entfernt (seit 3.0 nur noch ZXing)
# - PAPERLESS_DBSSLMODE durch PAPERLESS_DB_OPTIONS ersetzt
set -euo pipefail
# Feste Version. Bei einem Update bewusst hochsetzen, nicht "latest" verwenden.
PAPERLESS_VERSION="3.3.4"
# ---------------------------------------
# Helpers
# ---------------------------------------
log() { echo -e "\033[1;32m[INFO]\033[0m $*"; }
warn() { echo -e "\033[1;33m[WARN]\033[0m $*"; }
err() { echo -e "\033[1;31m[ERR ]\033[0m $*"; }
# ---------------------------------------
# Passwörter & Admin
# ---------------------------------------
prompt_for_password() {
local password password_confirm
if [[ "$1" == "PAPERLESS_PASSWORD" ]]; then
echo -e "\n💡 Hinweis: Dieses Passwort wird für den Linux-Benutzer 'paperless' und den Samba-Server verwendet."
echo -e "Es wird für den Zugriff auf freigegebene Samba-Ordner benötigt.\n"
fi
while true; do
echo -e "\n🔒 Bitte geben Sie das Passwort für **$1** ein:"
read -s password
echo -e "\n🔒 Bitte bestätigen Sie das Passwort:"
read -s password_confirm
if [[ "$password" == "$password_confirm" ]]; then
echo -e "\n✅ Passwort erfolgreich gesetzt für **$1**.\n"
eval "$2='$password'"
break
else
echo -e "\n❌ Die Passwörter stimmen nicht überein. Bitte erneut eingeben.\n"
fi
done
}
prompt_for_admin_user() {
echo -e "\n👤 Bitte geben Sie den **Admin-Benutzernamen** ein (Standard: paperless):"
read -r admin_user_input
ADMIN_USER="${admin_user_input:-paperless}"
echo -e "\n✅ Admin-Benutzer wurde auf **'$ADMIN_USER'** gesetzt.\n"
}
# Eingaben
prompt_for_password "PAPERLESS_PASSWORD" PAPERLESS_PASSWORD
prompt_for_admin_user
prompt_for_password "ADMIN_PASSWORD" ADMIN_PASSWORD
SAMBA_PASSWORD="$PAPERLESS_PASSWORD"
DB_PASSWORD="paperless"
# Seit Paperless-ngx 3.0 Pflicht: ein langer, zufaelliger Schluessel.
# Wird in die docker-compose.yml geschrieben und darf spaeter nicht mehr geaendert werden,
# sonst sind alle Sitzungen und Tokens ungueltig.
SECRET_KEY="$(openssl rand -hex 32)"
# ---------------------------------------
# Pakete & Docker-Repo
# ---------------------------------------
update_and_install_dependencies() {
log "Aktualisiere Paketliste und installiere benötigte Pakete…"
sudo apt update
sudo apt install -y apt-transport-https curl jq gnupg openssh-server \
samba samba-common-bin ca-certificates lsb-release
}
add_docker_repo() {
log "Füge Docker GPG-Schlüssel und Repository hinzu…"
sudo mkdir -p /etc/apt/keyrings
if [[ ! -f /etc/apt/keyrings/docker.gpg ]]; then
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
fi
. /etc/os-release
DOCKER_REPO="deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $VERSION_CODENAME stable"
echo "$DOCKER_REPO" | sudo tee /etc/apt/sources.list.d/docker.list >/dev/null
sudo apt update
}
# ---------------------------------------
# User/Gruppe
# ---------------------------------------
ensure_paperless_user_and_group() {
if ! getent group paperless &>/dev/null; then
log "Erstelle Gruppe 'paperless' mit GID 1002…"
sudo groupadd -g 1002 paperless
fi
if ! id -u paperless &>/dev/null; then
log "Erstelle Benutzer 'paperless' (UID 1002, GID 1002)…"
sudo useradd -m -s /bin/bash -u 1002 -g paperless paperless
echo "paperless:$PAPERLESS_PASSWORD" | sudo chpasswd
fi
}
# ---------------------------------------
# Docker installieren
# ---------------------------------------
install_docker() {
if ! command -v docker &>/dev/null; then
log "Installiere Docker…"
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker
fi
if ! groups paperless | grep -q "\bdocker\b"; then
log "Füge Benutzer 'paperless' zur Gruppe 'docker' hinzu…"
sudo usermod -aG docker paperless
fi
}
# ---------------------------------------
# AppArmor/runc-Bug NUR bei Bedarf mitigieren
# ---------------------------------------
mitigate_if_apparmor_bug() {
. /etc/os-release
if [[ "${ID:-}" != "ubuntu" ]]; then
log "Nicht Ubuntu – überspringe AppArmor/runc-Erkennung."
return 0
fi
if ! command -v docker >/dev/null 2>&1; then
warn "Docker noch nicht installiert – Erkennung wird später erneut versucht."
return 0
fi
sudo systemctl enable --now docker >/dev/null 2>&1 || true
docker pull hello-world >/dev/null 2>&1 || true
docker pull busybox:latest >/dev/null 2>&1 || true
local TEST_OUT=0 OUTPUT
if ! OUTPUT="$(docker run --rm --pull=never hello-world 2>&1)"; then
TEST_OUT=1
fi
if [[ $TEST_OUT -ne 0 ]]; then
if ! OUTPUT="$(docker run --rm --pull=never busybox:latest true 2>&1)"; then
TEST_OUT=2
else
TEST_OUT=0
fi
fi
if [[ $TEST_OUT -ne 0 ]] && echo "$OUTPUT" | grep -q 'net\.ipv4\.ip_unprivileged_port_start.*permission denied'; then
warn "Erkannt: AppArmor/runc-Problem beim Container-Start."
if ! dpkg -s containerd.io >/dev/null 2>&1; then
warn "containerd.io nicht installiert (vermutlich Ubuntu-Containerd). Downgrade wird übersprungen."
return 0
fi
local TARGET_VERSIONS=()
case "$VERSION_CODENAME" in
plucky) TARGET_VERSIONS=("1.7.28-1~ubuntu.25.04~plucky" "1.7.27-1") ;;
noble) TARGET_VERSIONS=("1.7.28-1~ubuntu.24.04~noble" "1.7.27-1") ;;
jammy) TARGET_VERSIONS=("1.7.28-1~ubuntu.22.04~jammy" "1.7.27-1") ;;
*) TARGET_VERSIONS=("1.7.27-1") ;;
esac
local CURR; CURR="$(dpkg-query -W -f='${Version}\n' containerd.io || true)"
for v in "${TARGET_VERSIONS[@]}"; do
if [[ "$CURR" == "$v" ]]; then
log "containerd.io bereits auf gewünschter Version ($v). Setze Hold."
sudo apt-mark hold containerd.io || true
return 0
fi
done
local AVAILABLE SELECTED
AVAILABLE="$(apt-cache madison containerd.io | awk '{print $3}')"
SELECTED=""
for v in "${TARGET_VERSIONS[@]}"; do
if echo "$AVAILABLE" | grep -qx "$v"; then SELECTED="$v"; break; fi
done
if [[ -z "$SELECTED" ]]; then
warn "Keine passende containerd.io-Version im Repo gefunden – Mitigation übersprungen."
return 0
fi
log "Mitigation: Downgrade/Pin containerd.io → $SELECTED"
sudo apt-mark unhold containerd.io || true
sudo apt-get install -y --allow-downgrades "containerd.io=${SELECTED}"
sudo apt-mark hold containerd.io
sudo systemctl restart containerd docker
else
log "Kein AppArmor/runc-Problem erkannt – keine Mitigation nötig."
fi
}
# ---------------------------------------
# Samba
# ---------------------------------------
configure_samba() {
sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak || true
sudo mkdir -p /data/paperless/{backup,restore,consume,data,media,export,postgresql/_data,redis/_data}
sudo chown -R paperless:paperless /data/paperless/
sudo chmod -R 770 /data/paperless/
if ! grep -q "^\[consume\]" /etc/samba/smb.conf; then
sudo tee -a /etc/samba/smb.conf >/dev/null <<'EOF'
[consume]
comment = Paperless Daten
path = /data/paperless/consume
browsable = yes
writable = yes
guest ok = no
create mask = 0770
directory mask = 0770
valid users = paperless
EOF
fi
if ! grep -q "^\[backup\]" /etc/samba/smb.conf; then
sudo tee -a /etc/samba/smb.conf >/dev/null <<'EOF'
[backup]
comment = Paperless Backup Daten
path = /data/paperless/backup
browsable = yes
writable = yes
guest ok = no
create mask = 0770
directory mask = 0770
valid users = paperless
EOF
fi
if ! grep -q "^\[restore\]" /etc/samba/smb.conf; then
sudo tee -a /etc/samba/smb.conf >/dev/null <<'EOF'
[restore]
comment = Paperless Restore Daten
path = /data/paperless/restore
browsable = yes
writable = yes
guest ok = no
create mask = 0770
directory mask = 0770
valid users = paperless
EOF
fi
(echo "$SAMBA_PASSWORD"; echo "$SAMBA_PASSWORD") | sudo smbpasswd -a paperless -s
sudo systemctl restart smbd
log "Samba Shares [consume], [backup], [restore] wurden konfiguriert."
}
# ---------------------------------------
# Compose schreiben
# ---------------------------------------
write_compose() {
log "Erstelle docker-compose.yml…"
sudo mkdir -p /home/paperless
sudo chown paperless:paperless /home/paperless
cat <<EOL | sudo tee /home/paperless/docker-compose.yml >/dev/null
services:
broker:
image: redis:8
container_name: broker
restart: unless-stopped
volumes:
- /data/paperless/redis/_data:/data
db:
image: postgres:17
container_name: db
restart: unless-stopped
volumes:
- /data/paperless/postgresql/_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: paperless
POSTGRES_USER: paperless
POSTGRES_PASSWORD: $DB_PASSWORD
gotenberg:
image: gotenberg/gotenberg:latest
container_name: paperless-gotenberg-1
restart: unless-stopped
command:
- "gotenberg"
- "--chromium-disable-javascript=false"
- "--chromium-allow-list=.*"
tika:
image: apache/tika:latest
container_name: tika
restart: unless-stopped
webserver:
image: ghcr.io/paperless-ngx/paperless-ngx:$PAPERLESS_VERSION
container_name: webserver
restart: unless-stopped
depends_on:
- db
- broker
- gotenberg
- tika
ports:
- "8001:8000"
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: $ADMIN_USER
PAPERLESS_ADMIN_PASSWORD: $ADMIN_PASSWORD
PAPERLESS_SECRET_KEY: "$SECRET_KEY"
PAPERLESS_REDIS: redis://broker:6379
PAPERLESS_DBENGINE: postgresql
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
PAPERLESS_CONSUMER_ENABLE_BARCODES: "true"
PAPERLESS_CONSUMER_ENABLE_ASN_BARCODE: "true"
PAPERLESS_EMAIL_TASK_CRON: '*/10 * * * *'
USERMAP_UID: "1002"
USERMAP_GID: "1002"
PAPERLESS_DB_OPTIONS: "sslmode=disable"
EOL
}
# ---------------------------------------
# DB starten, pg_hba absichern, dann Rest starten
# ---------------------------------------
bringup_with_pg_hba_fix() {
pushd /home/paperless >/dev/null
log "Starte zunächst NUR Redis & Postgres…"
sudo -u paperless docker compose up -d broker db
# Auf DB warten
log "Warte, bis Postgres erreichbar ist…"
for i in {1..60}; do
if sudo docker exec db pg_isready -q >/dev/null 2>&1; then
break
fi
sleep 2
done
# Subnetz der Compose-Network ermitteln
local NET="paperless_default"
local SUBNET
SUBNET="$(docker network inspect "$NET" 2>/dev/null | jq -r '.[0].IPAM.Config[0].Subnet' || true)"
if [[ -z "${SUBNET:-}" || "${SUBNET}" == "null" ]]; then
# Fallback: häufig 172.18.0.0/16
SUBNET="172.18.0.0/16"
warn "Konnte Subnetz nicht auslesen – nutze Fallback ${SUBNET}"
else
log "Ermitteltes Docker-Subnetz: ${SUBNET}"
fi
# pg_hba.conf patchen, falls Eintrag fehlt
log "Sichere pg_hba.conf gegen 'no pg_hba.conf entry … no encryption' ab…"
sudo docker exec db bash -lc "grep -q '${SUBNET} ' /var/lib/postgresql/data/pg_hba.conf || echo 'host all all ${SUBNET} scram-sha-256' >> /var/lib/postgresql/data/pg_hba.conf"
# Postgres reload (ohne DB-Login)
sudo docker exec db bash -lc 'kill -HUP 1'
# Kurzer Probe-Connect (ohne SSL)
export PGPASSWORD="$DB_PASSWORD"
if ! sudo docker exec -e PGPASSWORD="$DB_PASSWORD" db psql -U paperless -d paperless -c 'SELECT 1;' >/dev/null 2>&1; then
warn "Probe-Query fehlgeschlagen – fahre trotzdem fort (Paperless migriert beim Start)."
else
log "Probe-Query erfolgreich."
fi
unset PGPASSWORD
log "Starte nun gotenberg, tika und webserver…"
sudo -u paperless docker compose up -d gotenberg tika webserver
popd >/dev/null
}
# ---------------------------------------
# MAIN
# ---------------------------------------
update_and_install_dependencies
add_docker_repo
ensure_paperless_user_and_group
install_docker
mitigate_if_apparmor_bug
configure_samba
write_compose
bringup_with_pg_hba_fix
sleep 2
# Nur die Nutzdaten dem Benutzer paperless geben. Die Verzeichnisse von Postgres und Redis
# gehoeren den Benutzern in den Containern; ein chown darauf sperrt Postgres aus.
sudo chown -R paperless:paperless /data/paperless/{consume,data,media,export,backup,restore}
LOCAL_IP=$(hostname -I | awk '{print $1}')
echo -e "\n🚀 **Paperless-ngx $PAPERLESS_VERSION ist jetzt bereit!**"
echo -e "🔗 **Zugriff im Browser:** http://$LOCAL_IP:8001\n"
echo -e "🔁 **Bitte einmal neu booten, falls Docker neu installiert wurde.**"
⬆️ Upgrade von Paperless 2 auf Paperless 3 (bei vorhandener Installation)
ACHTUNG: Bitte zuvor unbedingt ein Backup der virtuellen Maschine oder des LXC-Containers in Proxmox machen!
Ein Upgrade auf eine neue Hauptversion ist kein normales Update. Die Datenbank wird umgebaut, der Suchindex neu erzeugt, und wenn dabei etwas schiefgeht, kann die bestehende Installation unbrauchbar werden. Zurück auf Paperless 2 geht es danach nicht mehr, die Datenbank lässt sich nicht zurückmigrieren. Das einzige Sicherheitsnetz ist euer Proxmox-Backup. Ohne Backup bitte gar nicht erst anfangen. Das Skript fragt deshalb auch ausdrücklich nach, ob ein Backup vorhanden ist.
Warum das Upgrade nicht mehr einfach so klappt
Mit Paperless-ngx 3.0 hat das Projekt drei Dinge geändert, die unsere bisherige docker-compose.yml nicht kennt:
- PAPERLESS_SECRET_KEY ist Pflicht. Fehlt der Schlüssel, startet der Container gar nicht mehr und hängt in einer Neustart-Schleife.
- Das Upgrade geht nur von Version 2.20.15 aus. Wer von einer älteren Version direkt auf 3 springt, bekommt die Meldung „Cannot upgrade to Paperless-ngx v3 from this version“.
- PAPERLESS_DBENGINE: postgresql ist Pflicht. Sonst weiß Paperless nicht, dass es die Postgres-Datenbank verwenden soll.
Weil in unserer Compose-Datei bisher image: ...:latest stand, hat jedes docker compose pull seit dem 24. Juli 2026 die Version 3 geladen. Genau das führt zu den Fehlern oben. Die gute Nachricht: Eure Dokumente und die Datenbank sind davon nicht betroffen, der Container startet nur nicht.
Woran ihr erkennt, dass es euch erwischt hat
Paperless ist im Browser nicht mehr erreichbar, und docker compose logs webserver in /home/paperless zeigt eine dieser Zeilen:
django.core.exceptions.ImproperlyConfigured: PAPERLESS_SECRET_KEY is not set or is the default 'change-me' value. s6-rc: warning: unable to start service init-migrations: command exited 1
[ERROR] [paperless.checks] V3 upgrade check failed: last applied documents migration is '1074_...'. Expected '1075_workflowaction_order' (v2.20.15). ?: (paperless.E002) Cannot upgrade to Paperless-ngx v3 from this version.
Keine Panik. Das Upgrade-Skript funktioniert auch in genau diesem Zustand, ihr müsst vorher nichts reparieren.
Schritt 1: Backup in Proxmox anlegen
- In Proxmox den Paperless-Container bzw. die VM auswählen, Reiter Backup, dann Backup now.
- Als Modus Stop wählen. Dann ist das Backup garantiert konsistent. Snapshot geht auch, birgt bei laufender Datenbank aber ein kleines Risiko.
- Warten, bis das Backup im Task-Log mit „TASK OK“ abgeschlossen ist. Erst dann weiter.
- Wer keinen Proxmox hat: Das komplette Verzeichnis
/data/paperlessund/home/paperlessbei gestoppten Containern sichern, z. B. mit backup_new.sh (siehe unten).
Schritt 2: Upgrade-Skript laden
Auf dem Paperless-System als root:
cd /root wget https://smarthomeundmore.de/wp-content/uploads/upgrade_paperless_v3.sh chmod +x upgrade_paperless_v3.sh
Schritt 3: Upgrade starten
./upgrade_paperless_v3.sh
Das Skript fragt einmal nach, ob das Backup vorhanden ist. Mit JA (in Großbuchstaben) geht es los. Danach erledigt es alle Schritte in der richtigen Reihenfolge:
- Sicherung der docker-compose.yml als
docker-compose.yml.vor-v3-DATUM - Prüfung, auf welchem Stand die Datenbank ist
- Ergänzen von
PAPERLESS_SECRET_KEYundPAPERLESS_DBENGINE, Entfernen der veralteten Zeilen - Zwischenschritt auf Paperless 2.20.15, falls nötig, und Warten, bis die Datenbank migriert ist
- Update auf Paperless 3.3.4 und Warten, bis der Container läuft
- Vergleich der Dokumentenzahl vorher und nachher
So sieht ein erfolgreicher Durchlauf aus (gekürzt):
[INFO] docker-compose.yml gesichert nach /home/paperless/docker-compose.yml.vor-v3-20261027-065035 [INFO] Dokumente in der Datenbank: 2128 [INFO] Letzte Datenbank-Migration: 1074_workflowrun_deleted_at_workflowrun_restored_at_and_more [INFO] Passe docker-compose.yml an ... [INFO] + PAPERLESS_SECRET_KEY erzeugt und eingetragen (seit 3.0 Pflicht) [INFO] + PAPERLESS_DBENGINE: postgresql eingetragen (seit 3.0 Pflicht) [INFO] - PAPERLESS_CONSUMER_BARCODE_SCANNER entfernt (seit 3.0 nur noch ZXing) [INFO] ~ PAPERLESS_DBSSLMODE durch PAPERLESS_DB_OPTIONS ersetzt [INFO] Zwischenschritt: Update auf 2.20.15 (Pflicht vor Version 3) ... [INFO] Paperless 2.20.15 laeuft, Datenbank ist bereit fuer Version 3. [INFO] Update auf Paperless-ngx 3.3.4 ... [INFO] Fertig. Paperless-ngx laeuft jetzt in Version 3.3.4. [INFO] Dokumente vorher: 2128, nachher: 2128
Bei meiner Installation mit rund 2100 Dokumenten hat der Zwischenschritt etwa eine Minute gedauert und das eigentliche Upgrade knapp zwei Minuten. Der Download der Images kommt je nach Internetanschluss dazu. Das Skript wartet bei jedem Schritt bis zu 30 Minuten, bevor es abbricht.
Schritt 4: Prüfen
- Im Browser anmelden. Alle Benutzer müssen sich einmal neu anmelden, weil der neue Secret Key alle alten Sitzungen ungültig macht.
- Unten links im Menü die Versionsnummer kontrollieren: 3.3.4.
- Dokumentenzahl prüfen. Das Skript zeigt sie am Ende, sie muss vorher und nachher gleich sein.
- Ein Testdokument in den consume-Ordner legen und schauen, ob es verarbeitet wird.
Was nach dem Upgrade anders ist
- Volltextsuche: Paperless 3 nutzt eine neue Suchmaschine (Tantivy) und baut den Index beim ersten Start automatisch neu auf. Bei vielen Dokumenten dauert das ein paar Minuten, so lange sind die Suchergebnisse unvollständig.
- Vorschläge für Tags und Korrespondenten: Das alte Klassifizierungsmodell passt nicht mehr zu Version 3. Paperless verwirft es und trainiert es innerhalb einer Stunde automatisch neu.
- Home-Assistant-Sensor: Der API-Token ist durch den neuen Secret Key ungültig. Unter Einstellungen → Benutzer → Token einen neuen erzeugen und in Home Assistant eintragen.
- Duplikate: Paperless 3 lehnt doppelte Dokumente nicht mehr ab, sondern nimmt sie an und markiert sie. Wer das alte Verhalten will, ergänzt in der docker-compose.yml unter
environmentdie ZeilePAPERLESS_CONSUMER_DELETE_DUPLICATES: "true". - Postgres 16: Wer das Postgres-Upgrade auf 17 (siehe Anhang) noch nicht gemacht hat, muss das für Paperless 3 nicht nachholen. Paperless 3 läuft mit beiden Versionen.
- Feste Version: In der Compose-Datei steht jetzt
3.3.4stattlatest. Für ein späteres Update tragt ihr die neue Versionsnummer ein und machtdocker compose pull && docker compose up -d.
Wenn etwas schiefgeht
- Das Skript bricht mit einer roten
[ERR ]-Zeile ab und zeigt die letzten Logzeilen des betroffenen Containers. Eure Daten sind in diesem Moment unverändert, das Skript löscht nichts. - Die alte Compose-Datei liegt als
docker-compose.yml.vor-v3-DATUMin/home/paperless. - Hilft das nicht weiter: In Proxmox das Backup aus Schritt 1 zurückspielen. Dann seid ihr wieder genau da, wo ihr angefangen habt.
- Das Skript kann beliebig oft gestartet werden. Es erkennt, was schon erledigt ist, und macht nur die fehlenden Schritte.
Der manuelle Weg
Wer lieber selbst Hand anlegt, macht in /home/paperless/docker-compose.yml diese Änderungen:
- Unter
environmentbeimwebserverergänzen (einen eigenen, langen Zufallswert verwenden, z. B. ausopenssl rand -hex 32):PAPERLESS_SECRET_KEY: "HIER-64-ZUFAELLIGE-ZEICHEN"PAPERLESS_DBENGINE: postgresql - Die Zeile
PAPERLESS_CONSUMER_BARCODE_SCANNER: ZXINGlöschen. - Falls vorhanden:
PAPERLESS_DBSSLMODE: disableersetzen durchPAPERLESS_DB_OPTIONS: "sslmode=disable". - Beim
webserverdas Image aufghcr.io/paperless-ngx/paperless-ngx:2.20.15setzen, danndocker compose pull && docker compose up -d. Mitdocker compose logs -f webserverwarten, bis „Apply database migrations“ durch ist und der Container läuft. - Das Image auf
ghcr.io/paperless-ngx/paperless-ngx:3.3.4setzen und noch einmaldocker compose pull && docker compose up -d.
Skript upgrade_paperless_v3.sh
#!/bin/bash
# upgrade_paperless_v3.sh - Stand 27.10.2026
#
# Hebt eine mit install_paperless.sh (smarthomeundmore.de) eingerichtete
# Paperless-ngx-Installation sicher von Version 2.x auf Version 3.x.
#
# Was das Skript macht:
# 1. docker-compose.yml sichern
# 2. fehlende Pflichtangaben fuer Paperless 3 ergaenzen
# (PAPERLESS_SECRET_KEY, PAPERLESS_DBENGINE), veraltete Zeilen entfernen
# 3. Zwischenschritt auf 2.20.15 (Pflicht laut Paperless-ngx, sonst startet 3.x nicht)
# 4. Update auf die Zielversion (ZIEL_VERSION)
#
# Voraussetzung: Vorher ein Backup der VM bzw. des LXC-Containers anlegen!
# Aufruf: sudo ./upgrade_paperless_v3.sh (fragt nach Bestaetigung)
# sudo ./upgrade_paperless_v3.sh --yes (ohne Rueckfrage, fuer restore_new.sh)
set -euo pipefail
ZIEL_VERSION="3.3.4"
ZWISCHEN_VERSION="2.20.15"
COMPOSE_DIR="/home/paperless"
COMPOSE="$COMPOSE_DIR/docker-compose.yml"
log() { echo -e "\033[1;32m[INFO]\033[0m $*"; }
warn() { echo -e "\033[1;33m[WARN]\033[0m $*"; }
err() { echo -e "\033[1;31m[ERR ]\033[0m $*"; }
# ---------------------------------------
# Vorpruefungen
# ---------------------------------------
if [[ $EUID -ne 0 ]]; then
err "Bitte als root ausfuehren: sudo ./upgrade_paperless_v3.sh"; exit 1
fi
if [[ ! -f "$COMPOSE" ]]; then
err "$COMPOSE nicht gefunden. Dieses Skript ist fuer Installationen mit install_paperless.sh gedacht."; exit 1
fi
if ! docker compose version >/dev/null 2>&1; then
err "docker compose nicht gefunden."; exit 1
fi
cd "$COMPOSE_DIR"
echo
echo "=============================================================="
echo " Paperless-ngx Upgrade auf Version $ZIEL_VERSION"
echo "=============================================================="
echo
warn "Vorher UNBEDINGT ein Backup der VM / des LXC-Containers anlegen!"
warn "Das Upgrade laesst sich nicht rueckgaengig machen, nur per Backup."
echo
if [[ "${1:-}" == "--yes" ]]; then
log "Bestaetigung per --yes uebersprungen (Aufruf aus einem anderen Skript)."
else
read -r -p "Backup vorhanden? Dann JA eingeben, um fortzufahren: " ANTWORT
[[ "$ANTWORT" == "JA" ]] || { echo "Abgebrochen."; exit 0; }
fi
# ---------------------------------------
# Hilfsfunktionen
# ---------------------------------------
db_sql() {
docker compose exec -T db psql -U paperless -d paperless -tAc "$1" 2>/dev/null | tr -d '[:space:]' || true
}
# Nach den alten Install-/Restore-Skripten gehoeren die Postgres-Dateien manchmal dem
# Benutzer paperless statt postgres. Dann scheitert jede Verbindung mit "Permission denied".
# Ein Neustart des db-Containers repariert das, weil das Postgres-Image die Rechte beim
# Start selbst korrigiert.
db_pruefen_und_heilen() {
local v
v=$(db_sql "SELECT 1;")
if [[ "$v" != "1" ]]; then
warn "Datenbank antwortet nicht. Starte den Container db einmal neu (repariert Dateirechte) ..."
docker compose restart db >/dev/null 2>&1 || true
for i in $(seq 1 30); do docker compose exec -T db pg_isready -q >/dev/null 2>&1 && break; sleep 2; done
sleep 3
v=$(db_sql "SELECT 1;")
fi
[[ "$v" == "1" ]]
}
# Hoechste nummerierte Migration der App documents (nur zur Anzeige)
letzte_documents_migration() {
db_sql "SELECT name FROM django_migrations WHERE app='documents' AND name ~ '^[0-9]{4}_' ORDER BY name DESC LIMIT 1;"
}
# 1 = Migration vorhanden, 0 = nicht vorhanden
hat_migration() {
local n; n=$(db_sql "SELECT count(*) FROM django_migrations WHERE app='documents' AND name='$1';")
[[ "${n:-0}" != "0" ]]
}
warte_auf_webserver() {
local max=$1 t=0 status
while (( t < max )); do
status=$(docker inspect -f '{{.State.Health.Status}}' webserver 2>/dev/null || echo "none")
if [[ "$status" == "healthy" ]]; then return 0; fi
local kaputt
kaputt=$(docker ps -a --format '{{.Names}} {{.Status}}' | grep -E '^(webserver|db|broker) Restarting' | awk '{print $1}' | head -1 || true)
if [[ -n "$kaputt" ]]; then
err "Der Container $kaputt startet immer wieder neu. Letzte Logzeilen:"
docker logs "$kaputt" --tail 30 2>&1 | tail -30
return 1
fi
sleep 10; t=$((t+10))
done
err "Zeitueberschreitung nach ${max}s. Logs: docker compose logs -f webserver"
return 1
}
# ---------------------------------------
# 1) Sicherung der Compose-Datei
# ---------------------------------------
SICHERUNG="$COMPOSE.vor-v3-$(date +%Y%m%d-%H%M%S)"
cp -a "$COMPOSE" "$SICHERUNG"
log "docker-compose.yml gesichert nach $SICHERUNG"
# ---------------------------------------
# 2) Datenbank und Ist-Zustand pruefen
# ---------------------------------------
log "Starte Datenbank, falls sie nicht laeuft ..."
docker compose up -d db broker >/dev/null
for i in $(seq 1 30); do docker compose exec -T db pg_isready -q >/dev/null 2>&1 && break; sleep 2; done
if ! db_pruefen_und_heilen; then
err "Keine Verbindung zur Datenbank. Logs: docker compose logs db"; exit 1
fi
DOCS_VORHER=$(db_sql "SELECT count(*) FROM documents_document;")
MIGRATION=$(letzte_documents_migration)
if [[ -z "$MIGRATION" ]]; then
err "Konnte den Datenbankstand nicht lesen. Laeuft der Container 'db'? Logs: docker compose logs db"; exit 1
fi
log "Dokumente in der Datenbank: $DOCS_VORHER"
log "Letzte Datenbank-Migration: $MIGRATION"
# Paperless 3 fasst die alten Migrationen zu '0001_squashed' zusammen. Ist dieser
# Eintrag vorhanden, laeuft die Datenbank bereits unter Version 3.
if hat_migration "0001_squashed"; then
log "Die Datenbank ist bereits auf dem Stand von Paperless 3. Zwischenschritt entfaellt."
SCHON_V3=1; BEREIT_FUER_V3=1
elif hat_migration "1075_workflowaction_order"; then
SCHON_V3=0; BEREIT_FUER_V3=1
else
SCHON_V3=0; BEREIT_FUER_V3=0
fi
# ---------------------------------------
# 3) docker-compose.yml fuer Paperless 3 anpassen
# ---------------------------------------
log "Passe docker-compose.yml an ..."
if ! grep -qE '^\s*PAPERLESS_SECRET_KEY:' "$COMPOSE"; then
SECRET_KEY="$(openssl rand -hex 32)"
sed -i "s|^\(\s*\)PAPERLESS_REDIS: |\1PAPERLESS_SECRET_KEY: \"$SECRET_KEY\"\n\1PAPERLESS_REDIS: |" "$COMPOSE"
log " + PAPERLESS_SECRET_KEY erzeugt und eingetragen (seit 3.0 Pflicht)"
else
log " = PAPERLESS_SECRET_KEY bereits vorhanden"
fi
if ! grep -qE '^\s*PAPERLESS_DBENGINE:' "$COMPOSE"; then
sed -i "s|^\(\s*\)PAPERLESS_DBHOST: |\1PAPERLESS_DBENGINE: postgresql\n\1PAPERLESS_DBHOST: |" "$COMPOSE"
log " + PAPERLESS_DBENGINE: postgresql eingetragen (seit 3.0 Pflicht)"
else
log " = PAPERLESS_DBENGINE bereits vorhanden"
fi
if grep -qE '^\s*PAPERLESS_CONSUMER_BARCODE_SCANNER:' "$COMPOSE"; then
sed -i '/^\s*PAPERLESS_CONSUMER_BARCODE_SCANNER:/d' "$COMPOSE"
log " - PAPERLESS_CONSUMER_BARCODE_SCANNER entfernt (seit 3.0 nur noch ZXing)"
fi
if grep -qE '^\s*PAPERLESS_DBSSLMODE:' "$COMPOSE"; then
sed -i 's|^\(\s*\)PAPERLESS_DBSSLMODE:.*|\1PAPERLESS_DB_OPTIONS: "sslmode=disable"|' "$COMPOSE"
log " ~ PAPERLESS_DBSSLMODE durch PAPERLESS_DB_OPTIONS ersetzt"
fi
if ! grep -qE '^\s*PAPERLESS_SECRET_KEY:|^\s*PAPERLESS_DBENGINE:' "$COMPOSE"; then
err "Anpassung fehlgeschlagen. Sicherung liegt unter $SICHERUNG"; exit 1
fi
setze_image() {
sed -i -E "s|^(\s*image: ghcr\.io/paperless-ngx/paperless-ngx:).*|\1$1|" "$COMPOSE"
grep -qE "paperless-ngx:$1\$" "$COMPOSE" || { err "Image-Zeile nicht gefunden."; exit 1; }
}
# ---------------------------------------
# 4) Zwischenschritt 2.20.15
# ---------------------------------------
if [[ $SCHON_V3 -eq 0 && $BEREIT_FUER_V3 -eq 0 ]]; then
log "Zwischenschritt: Update auf $ZWISCHEN_VERSION (Pflicht vor Version 3) ..."
setze_image "$ZWISCHEN_VERSION"
docker compose pull webserver
docker compose up -d
log "Warte, bis Paperless $ZWISCHEN_VERSION laeuft und die Migrationen durch sind ..."
warte_auf_webserver 1800 || { err "Zwischenschritt fehlgeschlagen. Compose-Sicherung: $SICHERUNG"; exit 1; }
if ! hat_migration "1075_workflowaction_order"; then
err "Unerwarteter Datenbankstand nach $ZWISCHEN_VERSION: $(letzte_documents_migration)"; exit 1
fi
log "Paperless $ZWISCHEN_VERSION laeuft, Datenbank ist bereit fuer Version 3."
elif [[ $SCHON_V3 -eq 0 ]]; then
log "Datenbank ist bereits auf dem Stand von 2.20.15. Zwischenschritt entfaellt."
fi
# ---------------------------------------
# 5) Update auf die Zielversion
# ---------------------------------------
log "Update auf Paperless-ngx $ZIEL_VERSION ..."
setze_image "$ZIEL_VERSION"
docker compose pull
docker compose up -d
log "Warte, bis Paperless $ZIEL_VERSION laeuft (Migrationen koennen einige Minuten dauern) ..."
warte_auf_webserver 2400 || { err "Update fehlgeschlagen. Compose-Sicherung: $SICHERUNG"; exit 1; }
DOCS_NACHHER=$(db_sql "SELECT count(*) FROM documents_document;")
VERSION_NEU=$(docker exec webserver grep -E "^__version__" /usr/src/paperless/src/paperless/version.py | grep -oE '[0-9]+, [0-9]+, [0-9]+' | tr -d ' ' | tr ',' '.')
echo
echo "=============================================================="
log "Fertig. Paperless-ngx laeuft jetzt in Version ${VERSION_NEU:-unbekannt}."
log "Dokumente vorher: $DOCS_VORHER, nachher: $DOCS_NACHHER"
if [[ "$DOCS_VORHER" != "$DOCS_NACHHER" ]]; then
warn "Die Dokumentenzahl hat sich geaendert. Bitte in der Oberflaeche pruefen."
fi
echo
log "Hinweise:"
echo " - Der Suchindex wird im Hintergrund neu aufgebaut. Die Volltextsuche liefert"
echo " erst dann vollstaendige Ergebnisse. Fortschritt: docker compose logs -f webserver"
echo " - Alle Benutzer muessen sich einmal neu anmelden."
echo " - Paperless 3 lehnt doppelte Dokumente nicht mehr automatisch ab. Wer das alte"
echo " Verhalten will, setzt PAPERLESS_CONSUMER_DELETE_DUPLICATES: \"true\" in der Compose-Datei."
echo " - Sicherung der alten Compose-Datei: $SICHERUNG"
echo "=============================================================="
💾 Backup und Restore
Es gibt zwei Wege, und beide funktionieren mit Paperless 2 und 3:
- Variante A – Export und Import (backup.sh / restore.sh): Paperless exportiert alle Dokumente samt Metadaten in ein ZIP, das sich auf jeder Paperless-Installation wieder importieren lässt. Dauert länger, ist aber unabhängig von Docker-Details.
- Variante B – 1:1-Abbild (backup_new.sh / restore_new.sh): Packt das komplette Verzeichnis
/data/paperlessin ein Archiv. Schnell, exakt, und der Restore stellt wirklich alles wieder her, auch Benutzer und Passwörter.
Variante A: Export und Import mit backup.sh und restore.sh
Backup: ./backup.sh ruft den Paperless-Exporter auf und legt das fertige ZIP in /data/paperless/backup ab. Von dort könnt ihr es über die Samba-Freigabe backup abholen.
Restore: Das ZIP in die Samba-Freigabe restore (also /data/paperless/restore) legen und ./restore.sh starten. Das Skript stoppt die Container, räumt die alten Daten weg, entpackt das ZIP, startet Paperless und importiert alles. Wichtig: restore.sh und upgrade_paperless_v3.sh müssen im selben Ordner liegen.
Wichtig: Mit dem Import kommen auch die Benutzer und Passwörter der Quellinstanz zurück. Nach dem Restore meldet ihr euch also mit den Zugangsdaten an, die auf dem alten System galten, nicht mit denen aus der Neuinstallation.
Hinweis zu Paperless 3: Ein Export aus Paperless 2 lässt sich nicht direkt in Paperless 3 importieren, der Importer kennt die alten Felder nicht mehr. restore.sh erkennt das an der Versionsangabe im Export, macht den Import dann mit Paperless 2.20.15 und ruft anschließend das Upgrade-Skript auf. Dauert etwas länger, läuft aber ohne euer Zutun.
Die Skripte zum Nachlesen: backup.sh und restore.sh
Variante B: 1:1-Backup und Restore mit backup_new.sh und restore_new.sh
Diese Variante (ursprünglich als Update vom 23.09.2025 ergänzt) sichert das komplette Datenverzeichnis als Archiv. Sie eignet sich besonders für den Umzug auf einen neuen Container oder eine neue VM.
Vorteile:
- Vollständiges Abbild von
/data/paperless(Dokumente, Postgres, Redis, Konfiguration) - Benutzer, Passwörter und Einstellungen bleiben exakt erhalten
- Schnell, weil nichts neu importiert oder OCR-verarbeitet werden muss
Wichtig: Nach dem Restore sind die alten Benutzer & Passwörter der Quellinstanz wieder aktiv – auch wenn beim Neuaufsetzen andere Zugangsdaten vergeben wurden.
A) Backup auf der Quellinstanz erstellen
cd /root ./backup_new.sh
Ablauf: Die Container werden gestoppt, ein komprimiertes Archiv wird in /data/paperless/backup erstellt (z. B. paperless-backup-2026-10-27_08-15.tar.gz), danach starten die Container wieder. Das Archiv auf die Zielinstanz kopieren, z. B. über die Samba-Freigabe backup oder mit scp.
B) Restore auf der Zielinstanz durchführen
- Zielinstanz wie gewohnt mit install_paperless.sh einrichten. Die Zugangsdaten, die ihr dabei vergebt, werden beim Restore durch die der Quellinstanz ersetzt.
- Das Archiv nach
/home/paperlesskopieren. Nicht nach/data/paperless/restore, dieses Verzeichnis wird beim Restore gelöscht. - restore_new.sh und upgrade_paperless_v3.sh müssen im selben Ordner liegen, z. B. beide in
/root. - Restore mit absolutem Pfad starten:
cd /root ./restore_new.sh /home/paperless/paperless-backup-2026-10-27_08-15.tar.gz
Ablauf: Die Container werden gestoppt, /data/paperless wird gelöscht und 1:1 mit den richtigen Besitzrechten aus dem Archiv wiederhergestellt. Danach prüft restore_new.sh automatisch, ob die wiederhergestellte Datenbank zur installierten Paperless-Version passt. Stammt das Backup aus Paperless 2 und die Zielinstanz läuft mit Paperless 3, übernimmt das Upgrade-Skript den Rest. Auch die Postgres-Version wird erkannt: Enthält das Backup noch eine Postgres-16-Datenbank, stellt das Skript die docker-compose.yml auf postgres:16 um, denn Postgres 17 kann die alten Datendateien nicht direkt lesen. Paperless 3 läuft damit problemlos, der Wechsel auf 17 bleibt optional.
Die Skripte zum Nachlesen: backup_new.sh und restore_new.sh
🧰 Anhang: Upgrade Postgres 16 zu Postgres 17 (bei vorhandener Installation)
Dieser Abschnitt betrifft nur Installationen aus der Zeit vor November 2025, die noch mit Postgres 16 laufen. Für Paperless 3 ist der Wechsel auf Postgres 17 nicht erforderlich, Paperless 3 läuft mit beiden Versionen.
ACHTUNG: Bitte zuvor unbedingt ein Backup der virtuellen Maschine oder des LXC Containers machen !
Zunächst begebt euch im Container oder der VM in das Verzeichnis /home/paperless. Dort findet ihr eine Datei docker-compose.yml.
Als ersten Schritt müssen wir nun die Docker Container beenden.
docker compose down
mit nano docker-compose.yml kontrollieren wir die Eintragungen der Compose Datei. Dabei ist folgender Abschnitt relevant:

Hier sieht man , dass aktuell das Image postgres:16 verwendet wird. Das brauchen wir für den Migrationsprozess in genau dieser Form. Merkt euch zudem auch den POSTGRES_USER , den brauchen wir für den nächsten Schritt.
Mit Strg+X beenden wir den Dateieditor und begeben uns in die Konsole.
Dort geben wir nun folgenden Befehl zum starten der Datenbank ein:
docker compose up -d db
Im nächsten Schritt sichern wir uns nun die aktuelle Datenbank:
docker exec -t db pg_dumpall -U DATENBANKUSER > all.sql
Bei DATENBANKUSER müsst ihr den User aus eurer docker-compose.yml eintragen. Im Beispiel ist es der User paperless.
Nachdem die Sicherung erfolgt ist, beenden wir erneut die Container:
docker compose down
Jetzt können wir erneut mit:
nano docker-compose.yml
unser Compose File editieren.
Jetzt müssen folgende Eintragungen angepasst werden:

Wir ändern also image: postgres:16 in image: postgres:17 und die Zeile volumes: …../_data in …./datav17
Danach starten wir erneut den Datenbank Container mit
docker compose up -d db
Jetzt müssen wir unsere Sicherung der Datenbank und die neu initialisierte Datenbank zurückkopieren.
Das können wir mit
cat all.sql | docker exec -i db psql -U DATENBANKUSER
machen. Dabei ist DATENBANKUSER wieder unser POSTGRES Datenbank Benutzer. In unserem Beispiel paperless.
Wenn der Import Vorgang nun ohne Fehler durchgelaufen ist, können wir mit
docker compose down docker compose up -d
alle Container wieder starten.
🧰 Anhang: Redis und Gotenberg Update
Um Redis und Gotenberg auf eine neue Version zu updaten sind auch wieder Anpassungen in der docker-compose.yml nötig.
Dazu müssen zunächst die Container gestoppt werden.
docker compose down
Danach editieren wir erneut die docker-compose.yml mit
nano docker-compose.yml
und ändern folgende Zeilen:

Hier tragt die gewünschte Redis Version ein. In meinem Beispiel habe ich von Version 7 auf 8 gewechselt.
Für Gotenberg gehen wir ähnlich vor. Hier habe ich mich entschieden, die „latest“ Variante zu verwenden.

Nach den Änderungen , beendet den Editor mit Strg+X und speichert mit „Yes“ die Datei.
Jetzt müssen wir noch die Container aktualisieren.
docker compose pull
und erneut starten.
docker compose up -d
Jetzt sollten alle Container in der aktuellen eingetragenen Version zur Verfügung stehen.
Hinweis: Ein Wechsel zurück auf eine ältere Redis-Version (z. B. von 8 auf 7) funktioniert nicht, weil Redis 7 das Datenformat von Redis 8 nicht lesen kann. Der Container startet dann nicht.
ASN QR Codes generieren
Avery Zweckform QR-Code Generator von Tobias L. Meier: https://tobiasmaier.info/asn-qr-code-label-generator/
Ergänzung & Dank an Murat
An dieser Stelle auch ein herzliches Dankeschön an Murat, der mich nach einem meiner YouTube-Videos auf eine interessante Ergänzung aufmerksam gemacht hat.
Er hatte bei der Nutzung des ASN-QR-Code-Label-Generators von Tobias Maier Schwierigkeiten, die QR-Codes korrekt und passgenau zu drucken. Deshalb hat er kurzerhand ein eigenes Projekt gestartet, mit dem sich mehr Kontrolle über den Druck realisieren lässt:
👉 ASN-QR-Code-Label-Generator von Murat auf GitHub
Vielleicht ist das auch für dich hilfreich, wenn du ähnliche Probleme beim Druck hast. Murat freut sich sicherlich über Feedback und Tests aus der Community.
Home Assistant Rest API Sensoren
Im Video habe ich auch gezeigt, wie man einen Sensor in Home Assistant erstellt, um sich die Anzahl der Dokumente im Posteingang anzeigen zu lassen. Die Informationen dazu habe ich von Flemming´s Blog, wo einige Beispielsensoren zu finden sind. Tolle Arbeit und sehr gut erklärt.
Monitoring Paperless-ngx in Home-Assistant – Flemming’s Blog
Nach einem Upgrade auf Paperless 3: Der API-Token für den Sensor ist durch den neuen Secret Key ungültig geworden. In Paperless unter Einstellungen → Benutzer → Token einen neuen Token erzeugen und in der Home-Assistant-Konfiguration eintragen.
Empfohlene Hardware für die Digitalisierung und die QR Codes
Ein weiterer Scanner, der häufiger im Kontext mit paperless-ngx genannt wird, ist der Brother ADS-1700W. Da ich diesen allerdings nicht selber getestet habe, kann ich keine direkte Empfehlung dazu aussprechen.
Solltest du in den Scripten noch Fehler finden, kannst du mir gerne deine Korrekturen als Mail zukommen lassen. Meine Kontakdaten findest du im Impressum.
Häufige Fragen (FAQ)
Wo kann ich Paperless NGX installieren?
Du kannst Paperless NGX unter Proxmox als LXC-Container oder als VM installieren, alternativ auch auf einem separaten PC bzw. Linux-Rechner.
Brauche ich viel Vorwissen für die Einrichtung?
Nein. Für den Beitrag stehen fertige Skripte bereit (Installation, Upgrade, Backup, Restore), die dir fast die gesamte Arbeit abnehmen.
Wie heißen die Samba-Freigaben?
Die Freigaben heißen consume, backup und restore. Genau diese Namen musst du verwenden, wenn du sie z. B. unter Windows einbindest. In älteren Videos hießen sie noch anders.
Kann ich Paperless NGX auch als Home-Assistant-Add-on nutzen?
Ja. Dafür gibt es eine separate Anleitung, die im Beitrag verlinkt ist.
Mein Paperless startet nach einem Update nicht mehr, im Log steht „PAPERLESS_SECRET_KEY is not set“. Was tun?
Du hast Paperless 3 geladen, aber deine docker-compose.yml ist noch für Version 2. Leg ein Backup in Proxmox an und führe upgrade_paperless_v3.sh aus. Das Skript repariert die Compose-Datei und macht das Upgrade in der richtigen Reihenfolge. Deine Dokumente sind nicht verloren.
Kann ich bei Paperless 2 bleiben?
Ja, dann trag in der docker-compose.yml statt latest die feste Version 2.20.15 ein. Sicherheitsupdates gibt es für die 2er-Reihe aber nicht mehr, deshalb ist das nur eine Übergangslösung.
Muss ich für Paperless 3 zuerst Postgres auf 17 bringen?
Nein. Paperless 3 läuft mit Postgres 16 und 17. Das Postgres-Upgrade im Anhang ist optional.
Ich habe ein Export-Backup aus Paperless 2. Kann ich es in Paperless 3 importieren?
Nicht direkt, der Importer von Paperless 3 kennt die alten Felder nicht. Das aktuelle restore.sh erkennt das automatisch, importiert mit Paperless 2.20.15 und hebt die Installation danach auf Version 3. Alternativ nutzt du das 1:1-Backup mit backup_new.sh und restore_new.sh.



