📁 Docker

docs/Docker

Paperless Docker Compose Dokumentation

Warum dieses Setup?

Das offizielle Installationskript von Paperless ist absolut nutzlos. Paperless knickt unter Last ein und DNS funktioniert dann nicht mehr. Deshalb verwenden wir statische IP-Adressen für alle Services.

Docker Compose Konfiguration

services:
  broker:
    image: docker.io/library/redis:7.4.2
    restart: unless-stopped
    volumes:
      - /data/redisdata:/data
    networks:
      paperless_net:
        ipv4_address: 172.18.0.5

  db:
    image: docker.io/library/postgres:16
    restart: unless-stopped
    volumes:
      - /data/pgdata:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: paperless
      POSTGRES_USER: paperless
      POSTGRES_PASSWORD: paperless
    networks:
      paperless_net:
        ipv4_address: 172.18.0.6

  webserver:
    image: ghcr.io/paperless-ngx/paperless-ngx:latest
    restart: unless-stopped
    depends_on:
      - db
      - broker
      - gotenberg
      - tika
    ports:
      - "80:8000"
    volumes:
      - /mnt/nfs/data:/usr/src/paperless/data
      - /mnt/nfs/media:/usr/src/paperless/media
      - /mnt/nfs/export:/usr/src/paperless/export
      - /mnt/nfs/consume:/usr/src/paperless/consume
    environment:
      # IP-Adressen statt Hostnamen
      PAPERLESS_REDIS: redis://172.18.0.5:6379
      PAPERLESS_DBHOST: 172.18.0.6
      PAPERLESS_TIKA_ENABLED: 1
      PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://172.18.0.7:3000
      PAPERLESS_TIKA_ENDPOINT: http://172.18.0.8:9998
      PAPERLESS_OCR_LANGUAGE: eng
      PAPERLESS_CSRF_TRUSTED_ORIGINS: http://server_IP{OR}domain.com
      PAPERLESS_CONSUMER_POLLING: 30
    networks:
      paperless_net:
        ipv4_address: 172.18.0.10

  gotenberg:
    image: docker.io/gotenberg/gotenberg:8.17
    restart: unless-stopped
    command:
      - "gotenberg"
      - "--chromium-disable-javascript=true"
      - "--chromium-allow-list=file:///tmp/.*"
    networks:
      paperless_net:
        ipv4_address: 172.18.0.7

  tika:
    image: ghcr.io/paperless-ngx/tika:latest
    restart: unless-stopped
    networks:
      paperless_net:
        ipv4_address: 172.18.0.8

networks:
  paperless_net:
    driver: bridge
    ipam:
      config:
        - subnet: 172.18.0.0/16

Ausführliche Erklärung des Scripts

Volume-Mapping Besonderheiten

Wichtig: PostgreSQL und Redis laufen auf lokalen Volumes (/data/), nicht auf NFS-Mounts, weil das nicht funktioniert. Datenbanken brauchen direkten Festplattenzugriff und vertragen keine Netzwerk-Latenzen oder Verbindungsabbrüche. Consumer und Webserver laufen problemlos auf NFS-Mounts.

Service: broker (Redis)

broker:
  image: docker.io/library/redis:7.4.2
  restart: unless-stopped
  volumes:
    - /data/redisdata:/data
  networks:
    paperless_net:
      ipv4_address: 172.18.0.5
  • Image: Offizielles Redis 7.4.2 Image von Docker Hub
  • restart: unless-stopped: Container startet automatisch nach Reboot, außer wenn manuell gestoppt
  • Volume: /data/redisdata:/data - Lokaler Pfad! Redis-Daten werden lokal gespeichert, nicht auf NFS, weil Redis sehr I/O-intensiv ist und Netzwerk-Latenzen nicht verträgt
  • Statische IP: 172.18.0.5 - Feste IP-Adresse im benutzerdefinierten Netzwerk

Service: db (PostgreSQL)

db:
  image: docker.io/library/postgres:16
  restart: unless-stopped
  volumes:
    - /data/pgdata:/var/lib/postgresql/data
  environment:
    POSTGRES_DB: paperless
    POSTGRES_USER: paperless
    POSTGRES_PASSWORD: paperless
  networks:
    paperless_net:
      ipv4_address: 172.18.0.6
  • Image: Offizielles PostgreSQL 16 Image
  • Volume: /data/pgdata:/var/lib/postgresql/data - Ebenfalls lokaler Pfad! PostgreSQL Datenbank läuft auf lokalem Storage, weil Datenbanken auf NFS/Netzwerk-Storage extrem schlecht performen und instabil werden
  • Environment Variables:
  • POSTGRES_DB: paperless - Erstellt Datenbank namens "paperless"
  • POSTGRES_USER: paperless - Benutzer für Paperless
  • POSTGRES_PASSWORD: paperless - Passwort (sollte geändert werden)
  • Statische IP: 172.18.0.6

Service: webserver (Paperless Hauptanwendung)

webserver:
  image: ghcr.io/paperless-ngx/paperless-ngx:latest
  restart: unless-stopped
  depends_on:
    - db
    - broker
    - gotenberg
    - tika
  ports:
    - "80:8000"
  volumes:
    - /mnt/nfs/data:/usr/src/paperless/data
    - /mnt/nfs/media:/usr/src/paperless/media
    - /mnt/nfs/export:/usr/src/paperless/export
    - /mnt/nfs/consume:/usr/src/paperless/consume
  • Image: Aktuellstes Paperless-ngx Image von GitHub Container Registry
  • depends_on: Startet erst, wenn alle anderen Services laufen
  • Port Mapping: 80:8000 - Host-Port 80 wird auf Container-Port 8000 gemappt (Web-Interface erreichbar über Port 80)
  • Volumes: Alle auf SMB-Mounts! Das funktioniert problemlos, weil:
  • /mnt/nfs/data - Anwendungsdaten (Konfiguration, Index, etc.) - SMB-Mount
  • /mnt/nfs/media - Gespeicherte Dokumente (PDFs, Bilder) - SMB-Mount
  • /mnt/nfs/export - Export-Ordner für Backups - SMB-Mount
  • /mnt/nfs/consume - Eingangsordner für neue Dokumente - SMB-Mount

Environment Variables:

environment:
  # Direkte IP-Verbindungen statt DNS
  PAPERLESS_REDIS: redis://172.18.0.5:6379
  PAPERLESS_DBHOST: 172.18.0.6

  # Dokumentenverarbeitung aktivieren
  PAPERLESS_TIKA_ENABLED: 1
  PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://172.18.0.7:3000
  PAPERLESS_TIKA_ENDPOINT: http://172.18.0.8:9998

  # OCR-Sprache
  PAPERLESS_OCR_LANGUAGE: eng

  # Sicherheit
  PAPERLESS_CSRF_TRUSTED_ORIGINS: http://server_IP{OR}domain.com

  # Consumer-Verhalten
  PAPERLESS_CONSUMER_POLLING: 30

  • PAPERLESS_REDIS: Direkte Verbindung zu Redis über IP 172.18.0.5, Port 6379
  • PAPERLESS_DBHOST: Direkte Verbindung zu PostgreSQL über IP 172.18.0.6
  • PAPERLESS_TIKA_ENABLED: Aktiviert Tika für bessere Textextraktion
  • PAPERLESS_TIKA_GOTENBERG_ENDPOINT: PDF-Konvertierung über Gotenberg (IP 172.18.0.7)
  • PAPERLESS_TIKA_ENDPOINT: Textextraktion über Tika (IP 172.18.0.8)
  • PAPERLESS_OCR_LANGUAGE: OCR-Sprache auf Englisch gesetzt
  • PAPERLESS_CSRF_TRUSTED_ORIGINS: Muss mit echter Server-IP/Domain ersetzt werden
  • PAPERLESS_CONSUMER_POLLING: Überprüft alle 30 Sekunden den consume-Ordner auf neue Dokumente

Service: gotenberg

gotenberg:
  image: docker.io/gotenberg/gotenberg:8.17
  restart: unless-stopped
  command:
    - "gotenberg"
    - "--chromium-disable-javascript=true"
    - "--chromium-allow-list=file:///tmp/.*"
  networks:
    paperless_net:
      ipv4_address: 172.18.0.7
  • Image: Gotenberg 8.17 für PDF-Konvertierung
  • Command: Zusätzliche Sicherheitseinstellungen - JavaScript deaktiviert, Dateizugriff eingeschränkt
  • Statische IP: 172.18.0.7 - Paperless verbindet sich direkt über diese IP

Service: tika

tika:
  image: ghcr.io/paperless-ngx/tika:latest
  restart: unless-stopped
  networks:
    paperless_net:
      ipv4_address: 172.18.0.8
  • Image: Spezielle Paperless-optimierte Tika-Version
  • Zweck: Extrahiert Text aus verschiedenen Dokumentformaten (Word, Excel, PowerPoint, etc.)
  • Statische IP: 172.18.0.8

Netzwerk-Konfiguration

networks:
  paperless_net:
    driver: bridge
    ipam:
      config:
        - subnet: 172.18.0.0/16
  • paperless_net: Benutzerdefiniertes Docker-Netzwerk
  • driver: bridge: Standard Bridge-Netzwerk
  • ipam: IP Address Management - definiert das Subnetz
  • subnet: 172.18.0.0/16: Großes Subnetz mit 65.534 verfügbaren IP-Adressen

Warum diese Aufteilung?

Lokale Volumes (/data/): - Redis und PostgreSQL brauchen schnellen, zuverlässigen Festplattenzugriff - Netzwerk-Storage verursacht bei Datenbanken Timeouts und Corruptions - I/O-intensive Operationen funktionieren nur lokal stabil - SMB wird für Paperless-Daten verwendet, weil NFS mit Berechtigungen Probleme macht

SMB-Volumes (/mnt/nfs/): - Paperless Anwendungsdaten können problemlos über SMB laufen - Dokumente und Medien sind weniger I/O-kritisch - SMB wird verwendet weil NFS mit Berechtigungen Probleme macht - Ermöglicht einfache Backups und Shared Storage

Script-Ausführung

Das Script holt mit Docker Compose die entsprechenden Container und führt diese aus. Jeder Container erhält eine eigene statische IP-Adresse im 172.18.0.0/16 Netzwerk. Dadurch sind alle Services auch unter hoher Last erreichbar, weil keine DNS-Auflösung stattfinden muss.