Paperless-ngx auf Debian 13 — Dokumente digitalisieren und verwalten

Paperless-ngx auf Debian 13 selbst hosten: Dokumente automatisch scannen, mit OCR durchsuchbar machen und zentral verwalten. Das papierlose Büro mit voller Datenhoheit.

Paperless-ngx auf Debian 13 selbst hosten: Dokumente automatisch scannen, mit OCR durchsuchbar machen und zentral verwalten. Das papierlose Büro mit voller Datenhoheit.

💡 Hinweis: Dieses Tutorial setzt voraus, dass du einen normalen Benutzer mit sudo-Rechten verwendest — wie im Tutorial Debian 13 Server absichern beschrieben. Außerdem solltest du Docker installiert und einen Reverse Proxy mit Nginx eingerichtet haben.

Einleitung — Was ist Paperless-ngx?

Wer einen Aktenordner irgendwo im Schrank stehen hat, kennt das Problem: Versicherungsschein finden? Erst mal eine halbe Stunde wühlen. Steuererklärung? Die letzten fünf Bescheide raussuchen, durchblättern. Die Lösung kommerziell: Evernote, Google Drive, Microsoft OneDrive — alle mit demselben Haken: Eure persönlichen Dokumente liegen auf fremden Servern.

Paperless-ngx ist das beste Open-Source-Dokumenten-Management-System für Self-Hosting. Ihr scannt Dokumente, ihr werft sie in einen Ordner — Paperless-ngx macht den Rest automatisch:

  • OCR (Texterkennung) — auch auf gescannten PDFs
  • Automatische Kategorisierung mit Tags, Korrespondenten, Dokumenttypen
  • Volltext-Suche über alle Dokumente
  • Web-UI und Mobile App
  • Multi-User mit Berechtigungen

Was Paperless-ngx kann

  • OCR via Tesseract — Auch deutsche Texte zuverlässig erkannt
  • Automatische Tagging mit Machine-Learning aus euren bisherigen Tags
  • Volltext-Suche über alle Dokumente
  • Consume-Folder — PDFs reinwerfen, automatisch verarbeitet
  • E-Mail-Import — Anhänge automatisch aus Postfach abholen
  • Multi-User & Berechtigungen — Familie/Team gemeinsam nutzen
  • Webhooks & API — Mit Home Assistant, n8n, Zapier verbinden
  • Mobile App über Drittanbieter wie paperless-mobile

Hardware-Empfehlung

DokumenteRAMCPUStorage
< 1.0002 GB2 Cores20 GB
1.000–10.0004 GB2 Cores50 GB
10.000+8 GB4 Cores200 GB+

In diesem Guide richten wir Paperless-ngx von Grund auf ein — Installation, OCR, Consume-Folder, Reverse Proxy und Backup-Strategie.


Voraussetzungen

  • Debian 13 Server — siehe Debian 13 Server-Guide
  • Docker & Docker Compose
  • Nginx als Reverse Proxy
  • Mindestens 2 GB RAM (4 GB empfohlen)
  • Domain (z.B. paperless.example.com)

Firewall & DNS

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw status

DNS-A-Record für paperless.example.com setzen.


Schritt 1: Verzeichnisstruktur

sudo mkdir -p /opt/paperless
sudo mkdir -p /var/lib/paperless/{data,media,export,consume}
cd /opt/paperless
  • data — Datenbank, Cache, Indizes
  • media — Eure originalen Dokumente
  • export — Export-Ziel für Backups/Migrations
  • consume — Hier werden neue Dokumente reingeworfen

💡 Tipp: Legt das media-Verzeichnis bewusst auf eine ausfallsichere Festplatte (RAID, regelmäßige Backups). Die Dokumente sind die wichtigste Datenquelle — die Datenbank ist nur der Index. Wenn die DB weg ist, könnt ihr neu indexieren. Wenn die Dokumente weg sind, sind sie weg.


Schritt 2: Konfigurationsdatei

sudo nano /opt/paperless/docker-compose.env

Inhalt:

# Zeitzone
PAPERLESS_TIME_ZONE=Europe/Berlin

# Sprache für OCR (deu, eng, fra, ...)
PAPERLESS_OCR_LANGUAGE=deu+eng

# URL, unter der Paperless erreichbar ist
PAPERLESS_URL=https://paperless.example.com

# Trusted Proxies (für Reverse Proxy)
PAPERLESS_USE_X_FORWARD_HOST=true
PAPERLESS_PROXY_SSL_HEADER='HTTP_X_FORWARDED_PROTO,https'

# Speicher-Pfade (intern im Container)
PAPERLESS_DATA_DIR=/usr/src/paperless/data
PAPERLESS_MEDIA_ROOT=/usr/src/paperless/media
PAPERLESS_CONSUMPTION_DIR=/usr/src/paperless/consume

# Datenbank
PAPERLESS_DBHOST=db
PAPERLESS_DBNAME=paperless
PAPERLESS_DBUSER=paperless
PAPERLESS_DBPASS=EUER_DB_PASSWORT

# Redis
PAPERLESS_REDIS=redis://broker:6379

# Admin-Account
PAPERLESS_ADMIN_USER=admin
PAPERLESS_ADMIN_PASSWORD=EUER_ADMIN_PASSWORT

# Geheimer Key (zufällig generieren!)
PAPERLESS_SECRET_KEY=EUER_GANZ_LANGER_ZUFAELLIGER_STRING

# Datei-Naming-Schema
PAPERLESS_FILENAME_FORMAT={created_year}/{correspondent}/{title}

Secret-Key generieren:

openssl rand -base64 64

.env-Datei absichern:

sudo chmod 600 /opt/paperless/docker-compose.env

⚠️ Wichtig: PAPERLESS_OCR_LANGUAGE=deu+eng — Tesseract macht OCR für alle angegebenen Sprachen parallel. Das kostet Rechenzeit. Wenn ihr 99% deutsche Dokumente habt, reicht deu — schneller und genauer.


Schritt 3: docker-compose.yml

sudo nano /opt/paperless/docker-compose.yml

Inhalt:

services:
  broker:
    image: docker.io/library/redis:7
    container_name: paperless-redis
    restart: unless-stopped
    volumes:
      - /var/lib/paperless/redis:/data

  db:
    image: docker.io/library/postgres:16
    container_name: paperless-db
    restart: unless-stopped
    volumes:
      - /var/lib/paperless/postgres:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: paperless
      POSTGRES_USER: paperless
      POSTGRES_PASSWORD: EUER_DB_PASSWORT

  webserver:
    image: ghcr.io/paperless-ngx/paperless-ngx:2.18.4
    container_name: paperless
    restart: unless-stopped
    depends_on:
      - db
      - broker
    ports:
      - "127.0.0.1:8000:8000"
    healthcheck:
      test: ["CMD", "curl", "-fs", "-S", "--max-time", "2", "http://localhost:8000"]
      interval: 30s
      timeout: 10s
      retries: 5
    volumes:
      - /var/lib/paperless/data:/usr/src/paperless/data
      - /var/lib/paperless/media:/usr/src/paperless/media
      - /var/lib/paperless/export:/usr/src/paperless/export
      - /var/lib/paperless/consume:/usr/src/paperless/consume
    env_file:
      - docker-compose.env

⚠️ Wichtig: Pinnt die Image-Version (z.B. paperless-ngx:2.18.4). Mit :latest würde ein Auto-Update euch eine breaking Change einfangen können.

POSTGRES_PASSWORD muss dem Wert in docker-compose.env (PAPERLESS_DBPASS) entsprechen.


Schritt 4: Paperless starten

cd /opt/paperless
sudo docker compose up -d

Erster Start dauert 2-3 Minuten — DB-Migrationen, Index-Erstellung, OCR-Dictionary-Download.

sudo docker compose logs -f webserver

Bei Listening at: http://0.0.0.0:8000 ist Paperless bereit.

Health-Check

curl -I http://127.0.0.1:8000

Sollte HTTP/1.1 200 OK (oder Redirect) zurückgeben.


Schritt 5: Nginx Reverse Proxy

sudo nano /etc/nginx/sites-available/paperless.example.com

Inhalt:

server {
    listen 80;
    listen [::]:80;
    server_name paperless.example.com;

    location /.well-known/acme-challenge/ {
        root /var/www/html;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name paperless.example.com;

    ssl_certificate /etc/letsencrypt/live/paperless.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/paperless.example.com/privkey.pem;

    # Größe für Dokument-Uploads
    client_max_body_size 100M;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_http_version 1.1;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $host;

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        proxy_redirect off;
    }
}

Aktivieren und SSL holen:

sudo ln -s /etc/nginx/sites-available/paperless.example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo certbot --nginx -d paperless.example.com

Im Browser: https://paperless.example.com. Login mit dem Admin-Account aus der .env-Datei.

Geschafft! Paperless-ngx ist erreichbar und einsatzbereit. Jetzt kommt der spannende Teil — der Consume-Folder.


Schritt 6: Erste Dokumente einlesen

Es gibt drei Wege, Dokumente in Paperless zu bekommen:

Variante A: Consume-Folder (empfohlen)

Der absolute Hauptweg. PDFs werden einfach in einen Ordner gelegt, Paperless erkennt sie automatisch:

# Beispiel: Ein PDF einwerfen
sudo cp ~/Downloads/rechnung.pdf /var/lib/paperless/consume/

Innerhalb von Sekunden wird Paperless die Datei verarbeiten:

  1. OCR durchführen
  2. Datum erkennen
  3. Korrespondent vorschlagen
  4. Tags zuweisen (basierend auf vorigen Dokumenten)
  5. PDF mit eingebettetem Text in media/ ablegen
  6. Original aus consume/ löschen

Im Web-UI seht ihr das neue Dokument unter Documents.

Variante B: Web-Upload

In der Web-UI: Big Plus-Button oder Drag-and-Drop. Funktioniert für einzelne Dokumente.

Variante C: E-Mail-Import

In Administration → Mail Accounts: IMAP-Server eingeben. Paperless holt regelmäßig Anhänge aus dem Postfach.

💡 Tipp: Den Consume-Folder per Samba/CIFS im Netzwerk freigeben — dann können Familie/Mitbewohner Dokumente direkt vom Scanner aus reinwerfen. Das macht Paperless erst richtig zum Familien-DMS.


Schritt 7: Tags, Korrespondenten und Dokumenttypen

Paperless organisiert über drei Achsen:

  • Korrespondenten — Wer ist Absender? (z.B. Krankenkasse, Vermieter, Finanzamt)
  • Dokumenttypen — Was für ein Dokument? (z.B. Rechnung, Vertrag, Bescheid)
  • Tags — Beliebige Labels (z.B. Wichtig, 2024, Steuer)

Diese in der Web-UI unter Settings → Tags / Document Types / Correspondents anlegen.

Auto-Matching aktivieren

Beim Anlegen eines Tags/Korrespondenten könnt ihr Matching algorithm konfigurieren:

  • Auto — Machine Learning lernt aus euren bestehenden Zuordnungen
  • Any word — Jedes der angegebenen Wörter trifft
  • All words — Alle Wörter müssen vorkommen
  • Exact match — Genauer Substring
  • Regular expression — Regex-Pattern

Beispiel: Korrespondent TelekomMatch: any word → Wörter: Telekom, Magenta, T-Mobile. Jede neue Telekom-Rechnung wird automatisch zugeordnet.

💡 Empfehlung: Investiert eine Stunde in saubere Tags und Auto-Matching-Regeln. Danach läuft 80% der Verschlagwortung automatisch — und ihr werdet nie wieder eine Rechnung händisch ablegen.


Schritt 8: Filename-Format & Fallback-Verhalten

In der .env steht PAPERLESS_FILENAME_FORMAT={created_year}/{correspondent}/{title}. Das bedeutet:

/var/lib/paperless/media/
  2024/
    Krankenkasse/
      Beitragsbescheid.pdf
    Stadtwerke/
      Stromrechnung.pdf
  2025/
    ...

Vorteil: Auch ohne Paperless-DB sind eure Dokumente sinnvoll strukturiert auf der Platte.


Schritt 9: Mobile App einrichten

Es gibt paperless-mobile für Android und iOS — ein Drittanbieter-Client, sehr gut gepflegt.

Im App-Store nach Paperless Mobile suchen. Im Setup:

  • Server-URL: https://paperless.example.com
  • Authentication: Username + Passwort, oder API-Token

API-Token in der Web-UI: Settings → My Profile → API Token → Generate.

Mit der App könnt ihr Dokumente per Kamera scannen, automatisch zuschneiden und direkt zu Paperless hochladen.


Backups

Paperless hat vier kritische Datenquellen:

  • /var/lib/paperless/media/ — Originale Dokumente (am wichtigsten!)
  • /var/lib/paperless/data/ — Such-Index (kann neu erzeugt werden)
  • PostgreSQL-DB — Metadaten, Tags, Korrespondenten
  • /opt/paperless/docker-compose.env — Konfiguration

Variante A: Document Exporter (offiziell empfohlen)

Paperless hat einen eingebauten Exporter, der alles als ZIP-konform packt:

sudo docker exec -it paperless document_exporter /usr/src/paperless/export

Das Ergebnis liegt in /var/lib/paperless/export/ und enthält alle Dokumente plus Metadaten als JSON. Wiederherstellbar mit document_importer.

Variante B: Backup-Script

sudo nano /usr/local/bin/paperless-backup.sh

Inhalt:

#!/bin/bash
set -e

BACKUP_DIR="/var/backups/paperless"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
RETENTION_DAYS=7

mkdir -p "$BACKUP_DIR"

# Document-Exporter
docker exec paperless document_exporter -na /usr/src/paperless/export

# Postgres-Dump
docker exec -t paperless-db pg_dumpall -U paperless | gzip > "$BACKUP_DIR/db-$TIMESTAMP.sql.gz"

# Export-Ordner archivieren
tar -czf "$BACKUP_DIR/export-$TIMESTAMP.tar.gz" -C /var/lib/paperless/export .

# Konfiguration
cp /opt/paperless/docker-compose.env "$BACKUP_DIR/env-$TIMESTAMP.bak"

# Alte Backups
find "$BACKUP_DIR" -type f -mtime +$RETENTION_DAYS -delete

echo "Backup completed: $TIMESTAMP"

Ausführbar machen und mit systemd-Timer automatisieren — siehe restic-Tutorial.

sudo chmod +x /usr/local/bin/paperless-backup.sh

⚠️ Best Practice: Eure Dokumente sind oft jahrelange Aufzeichnungen — Verträge, Steuern, Rechnungen. Sichert sie dreifach: Lokal, an einem zweiten Ort (z.B. NAS), und Off-Site (Cloud-Bucket per restic). 3-2-1-Regel.


Updates

Vor jedem Update Release-Notes lesen!

cd /opt/paperless

# Image-Tag in docker-compose.yml auf neue Version
sudo nano docker-compose.yml

# Backup VOR dem Update!
sudo /usr/local/bin/paperless-backup.sh

# Update
sudo docker compose pull
sudo docker compose up -d

Erste Anmeldung nach Update kann dauern (DB-Migrationen).


Zusammenfassung & Checkliste

SchrittStatus
Debian 13 + Docker installiert
Verzeichnisstruktur unter /var/lib/paperless
docker-compose.env mit allen Werten gefüllt
Image-Version gepinnt
Paperless-Container läuft
Web-UI erreichbar via Reverse Proxy
SSL-Zertifikat eingerichtet
Test-Dokument in Consume-Folder eingelesen
Tags, Korrespondenten, Dokumenttypen angelegt
Auto-Matching konfiguriert
Mobile App verbunden (optional)
Filename-Format gesetzt
Backup-Script eingerichtet
Backup einmal manuell getestet

Troubleshooting

Paperless verarbeitet Consume-Folder nicht

  • Container-Volume-Mount korrekt? sudo docker exec paperless ls /usr/src/paperless/consume
  • File-Permissions: Container-User (paperless) muss lesen können
  • Logs: sudo docker compose logs -f webserver

OCR-Sprache wird nicht erkannt

  • PAPERLESS_OCR_LANGUAGE in .env korrekt? Mehrere mit + trennen: deu+eng
  • Tesseract-Daten heruntergeladen? Container neu starten erzwingt Re-Download

Suche findet Dokument nicht

  • Index möglicherweise nicht aktuell. Reindex erzwingen:
sudo docker exec paperless document_index reindex

Hoher CPU-Verbrauch beim Konsumieren

OCR ist rechenintensiv. Bei vielen Dokumenten in Consume:

  • PAPERLESS_TASK_WORKERS=2 in .env reduzieren auf 1
  • PAPERLESS_THREADS_PER_WORKER=2 reduzieren

„django.db.utils.OperationalError“

DB-Verbindung weg. paperless-db-Container prüfen:

sudo docker compose ps
sudo docker compose restart db webserver

Mobile App: Login schlägt fehl

  • Server-URL korrekt? Mit https://
  • API-Token statt Passwort versuchen
  • Trusted Proxy / X-Forwarded-Proto-Header in Nginx korrekt gesetzt?

Nächste Schritte

  • Authentik-OIDC für Paperless — falls ihr Authentik habt
  • Samba-Share für Consume-Folder — Familie kann direkt vom Scanner reinwerfen
  • n8n-Workflow — Automatisches Verschieben aus E-Mail-Anhang in Consume
  • Jahres-Archiv-Strategie — Steuerunterlagen 10 Jahre, Verträge dauerhaft
  • GoBD-konformes Archivieren — für Selbstständige & Unternehmen wichtig

Habt ihr Fragen oder Probleme? Schreibt es in die Kommentare — ich helfe gerne!

Kommentar hinterlassen