Papermerge installieren – Anleitung für Portainer & ZimaOS als native App

Viktor Dite, Autor des Beitrags

Von - Publiziert in Homeserver
Dipl. Informatiker und Tech-Blogger seit 2006.


Ich wurde gefragt, ob ich nicht eine Anleitung für die Papermerge Installation erstellen könnte. Wer schon mal in die offizielle Dokumentation geschaut hat, weiß: Sie ist unglaublich modular. Man findet Anleitungen für die App, für den OCR-Worker, für die Datenbank – aber kaum eine funktionierende „Copy & Paste“-Lösung für ein komplettes System. Ich biete Dir hier zwei Lösungen an, einmal für die native Installation unter ZimaOS als App oder über Portainer. Du entscheidest, welche Version Du installieren willst.

Papermerge installieren
Papermerge DMS installieren

Nach einigem Basteln und Debuggen (besonders mit den Dateirechten von Apache Solr!) habe ich jetzt eine perfekt laufende Konfiguration.

Vorbereitung: Ordner anlegen

Bevor wir anfangen, müssen wir auf dem Server (z.B. auf deinem RAID oder deiner großen SSD) die Ordnerstruktur anlegen. Papermerge braucht drei Speicherorte:

  1. pgdata: Für die Datenbank.
  2. media_data: Für deine PDFs und Dokumente.
  3. solr_data: Für den Suchindex.

Erstelle diese Ordnerstruktur (passe den Pfad /media/RAID1/DATA/ an deine Orner-Struktur an):

/media/RAID1/DATA/Papermerge/pgdata
/media/RAID1/DATA/Papermerge/media_data
/media/RAID1/DATA/Papermerge/solr_data

Methode 1: Installation über Portainer (Empfohlen)

Das ist der sauberste Weg. Portainer bietet uns „Stacks“ (Docker Compose), bessere Logs und volle Kontrolle über das Netzwerk.

Schritt 1: Stack erstellen

  1. Öffne Portainer (auf deinem ZimaOS).
  2. Gehe links auf Stacks und klicke oben rechts auf Add stack.
  3. Nenne den Stack papermerge.
  4. Kopiere den folgenden Code in den Web-Editor.
Papermerge installieren
Papermerge in Portainer installieren

Schritt 2: Die Docker-Compose YAML (Portainer)

Wichtig: Ich habe an den entsprechenden Stellen Kommentare eingefügt (# <--- ...), wo du unbedingt eigene Passwörter setzen solltest!

version: "3.8"

services:
  # Dieser Hilfs-Container repariert automatisch die Rechte für die Suchmaschine Solr
  init-solr:
    image: solr:9.7
    container_name: fix-solr-permissions
    user: root
    command: chown -R 8983:8983 /var/solr
    volumes:
      # ACHTUNG: Pfad anpassen!
      - /media/RAID1/DATA/Papermerge/solr_data:/var/solr
    networks:
      - papermerge_net

  db:
    image: postgres:16.1
    restart: unless-stopped
    environment:
      - POSTGRES_DB=pmgdb
      - POSTGRES_USER=pmg_user
      # ÄNDERN: Dein Datenbank-Passwort
      - POSTGRES_PASSWORD=Vergib_Hier_Ein_Sicheres_DB_Passwort! # <--- ÄNDERN
    volumes:
      # ACHTUNG: Pfad anpassen!
      - /media/RAID1/DATA/Papermerge/pgdata:/var/lib/postgresql/data
    healthcheck:
      # Prüft, ob die DB bereit ist, damit die App nicht zu früh startet
      test: ["CMD-SHELL", "pg_isready -U pmg_user -d pmgdb"]
      interval: 5s
      timeout: 10s
      retries: 5
      start_period: 10s
    networks:
      - papermerge_net

  redis:
    image: redis:7.2
    restart: unless-stopped
    environment:
      - ALLOW_EMPTY_PASSWORD=yes
    networks:
      - papermerge_net

  solr:
    image: solr:9.7
    restart: unless-stopped
    command:
      - solr-precreate
      - pmg
    volumes:
      # ACHTUNG: Pfad anpassen!
      - /media/RAID1/DATA/Papermerge/solr_data:/var/solr
    depends_on:
      init-solr:
        condition: service_completed_successfully
    networks:
      - papermerge_net

  webapp:
    image: papermerge/papermerge:3.5.3
    restart: unless-stopped
    ports:
      - "12000:80" # Erreichbar unter http://server-ip:12000
    environment:
      - PAPERMERGE__AUTH__USERNAME=admin
      # ÄNDERN: Dein Login-Passwort für die Weboberfläche
      - PAPERMERGE__AUTH__PASSWORD=Vergib_Hier_Ein_Admin_Login_Passwort! # <--- ÄNDERN
      # ÄNDERN: Muss mit dem DB-Passwort oben übereinstimmen
      - PAPERMERGE__DATABASE__URL=postgresql://pmg_user:Vergib_Hier_Ein_Sicheres_DB_Passwort!@db:5432/pmgdb # <--- ÄNDERN
      - PAPERMERGE__MAIN__MEDIA_ROOT=/var/media/pmg
      - PAPERMERGE__OCR__DEFAULT_LANG_CODE=deu
      - PAPERMERGE__OCR__LANG_CODES=deu,eng
      - PAPERMERGE__REDIS__URL=redis://redis:6379/0
      - PAPERMERGE__SEARCH__URL=solr://solr:8983/pmg
      # ÄNDERN: Generiere einen zufälligen Key (z.B. wild auf die Tastatur hauen)
      - PAPERMERGE__SECURITY__SECRET_KEY=Hier_Muss_Ein_Langer_Zufalls_String_Hin_XyZ123 # <--- ÄNDERN
    volumes:
      # ACHTUNG: Pfad anpassen!
      - /media/RAID1/DATA/Papermerge/media_data:/var/media/pmg
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
      solr:
        condition: service_started
    networks:
      - papermerge_net

  ocr_worker:
    image: papermerge/ocrworker:0.3.1
    restart: unless-stopped
    command: worker
    environment:
      - OCR_WORKER_ARGS=-Q ocr -c 2
      # ÄNDERN: Muss mit dem DB-Passwort oben übereinstimmen
      - PAPERMERGE__DATABASE__URL=postgresql://pmg_user:Vergib_Hier_Ein_Sicheres_DB_Passwort!@db:5432/pmgdb # <--- ÄNDERN
      - PAPERMERGE__MAIN__MEDIA_ROOT=/var/media/pmg
      - PAPERMERGE__REDIS__URL=redis://redis:6379/0
    volumes:
      # ACHTUNG: Pfad anpassen!
      - /media/RAID1/DATA/Papermerge/media_data:/var/media/pmg
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    networks:
      - papermerge_net

  i3worker:
    image: papermerge/i3worker:0.3
    restart: unless-stopped
    command: worker
    environment:
      - I3_WORKER_ARGS=-Q i3 -c 2
      # ÄNDERN: Muss mit dem DB-Passwort oben übereinstimmen
      - PAPERMERGE__DATABASE__URL=postgresql://pmg_user:Vergib_Hier_Ein_Sicheres_DB_Passwort!@db:5432/pmgdb # <--- ÄNDERN
      - PAPERMERGE__REDIS__URL=redis://redis:6379/0
      - PAPERMERGE__SEARCH__URL=solr://solr:8983/pmg
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
      solr:
        condition: service_started
    networks:
      - papermerge_net

networks:
  papermerge_net:
    driver: bridge

Troubleshooting: „Permission Denied“ bei Solr

Das häufigste Problem bei der Installation ist der Suchindex Solr. Er startet, stürzt ab und startet neu (Bootloop). Der Grund: Solr läuft intern als Benutzer 8983, aber die Ordner auf dem ZimaOS gehören oft root.

In meiner Konfiguration oben habe ich dafür den Dienst init-solr eingebaut. Das ist ein winziger „Wegwerf-Container“, der kurz vor dem eigentlichen Start hochfährt, die Rechte des Ordners /media/RAID1/DATA/Papermerge/solr_data repariert (chown 8983) und sich dann sofort wieder beendet (Exit 0).

Das ist viel eleganter, als manuell im Terminal mit chown hantieren zu müssen!

Schritt 3: Starten

Klicke auf Deploy the stack. Portainer lädt jetzt alle Images herunter. Das erste Hochfahren dauert etwas, besonders bis die Datenbank den „Healthy“-Status meldet.

App aufrufen

Nach der fertigen Installation lässt sich die App unter http://DEINE-IP:12000 aufrufen.

Methode 2: ZimaOS Custom App (Nativ)

Wer Portainer nicht nutzen möchte, kann die App auch direkt über die ZimaOS-Oberfläche importieren.

Achtung: Hier ist es extrem wichtig, dass wir unten in der YAML ein eigenes Netzwerk definieren (networks:), sonst finden sich die Container (Datenbank, Solr, Webapp) gegenseitig nicht, da ZimaOS Apps standardmäßig isoliert.

Papermerge installieren unter ZimaOS
Papermerge installieren unter ZimaOS
  • Klicke im ZimaOS Dashboard auf das Plus oben rechts über den Apps
  • Klicke dann auf Install custom App.
  • Klick dann auf Import
  • Füge den yaml Code von weiter oben im Beitrag ein:
name: papermerge
services:
  db:
    image: postgres:16.1
    environment:
      - POSTGRES_DB=pmgdb
      - POSTGRES_USER=pmg_user
      - POSTGRES_PASSWORD=Vergib_Hier_Ein_Sicheres_DB_Passwort! # <--- ÄNDERN
    volumes:
      - /media/RAID1/DATA/Papermerge/pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U pmg_user -d pmgdb"]
      interval: 5s
      timeout: 10s
    networks:
      - papermerge_net

  redis:
    image: redis:7.2
    environment:
      - ALLOW_EMPTY_PASSWORD=yes
    networks:
      - papermerge_net

  solr:
    image: solr:9.7
    # Hier kein depends_on mehr zum init-container
    command:
      - solr-precreate
      - pmg
    volumes:
      - /media/RAID1/DATA/Papermerge/solr_data:/var/solr
    networks:
      - papermerge_net

  webapp:
    image: papermerge/papermerge:3.5.3
    ports:
      - "12000:80"
    environment:
      - PAPERMERGE__AUTH__USERNAME=admin
      - PAPERMERGE__AUTH__PASSWORD=Vergib_Hier_Ein_Admin_Login_Passwort! # <--- ÄNDERN
      - PAPERMERGE__DATABASE__URL=postgresql://pmg_user:Vergib_Hier_Ein_Sicheres_DB_Passwort!@db:5432/pmgdb # <--- ÄNDERN
      - PAPERMERGE__MAIN__MEDIA_ROOT=/var/media/pmg
      - PAPERMERGE__OCR__DEFAULT_LANG_CODE=deu
      - PAPERMERGE__OCR__LANG_CODES=deu,eng
      - PAPERMERGE__REDIS__URL=redis://redis:6379/0
      - PAPERMERGE__SEARCH__URL=solr://solr:8983/pmg
      - PAPERMERGE__SECURITY__SECRET_KEY=Hier_Muss_Ein_Langer_Zufalls_String_Hin_XyZ123 # <--- ÄNDERN
    volumes:
      - /media/RAID1/DATA/Papermerge/media_data:/var/media/pmg
    depends_on:
      db:
        condition: service_healthy
    networks:
      - papermerge_net

  ocr_worker:
    image: papermerge/ocrworker:0.3.1
    command: worker
    environment:
      - OCR_WORKER_ARGS=-Q ocr -c 2
      - PAPERMERGE__DATABASE__URL=postgresql://pmg_user:Vergib_Hier_Ein_Sicheres_DB_Passwort!@db:5432/pmgdb # <--- ÄNDERN
      - PAPERMERGE__MAIN__MEDIA_ROOT=/var/media/pmg
      - PAPERMERGE__REDIS__URL=redis://redis:6379/0
    volumes:
      - /media/RAID1/DATA/Papermerge/media_data:/var/media/pmg
    networks:
      - papermerge_net

  i3worker:
    image: papermerge/i3worker:0.3
    command: worker
    environment:
      - I3_WORKER_ARGS=-Q i3 -c 2
      - PAPERMERGE__DATABASE__URL=postgresql://pmg_user:Vergib_Hier_Ein_Sicheres_DB_Passwort!@db:5432/pmgdb # <--- ÄNDERN
      - PAPERMERGE__REDIS__URL=redis://redis:6379/0
      - PAPERMERGE__SEARCH__URL=solr://solr:8983/pmg
    networks:
      - papermerge_net

networks:
  papermerge_net:
    driver: bridge

x-casaos:
  author: self
  icon: https://icon.casaos.io/main/all/papermerge.png
  title:
    en_us: Papermerge DMS

Der wichtige Zusatzschritt (Rechte setzen)

Wichtig: Da Solr spezielle Schreibrechte benötigt, wird der Solr-Container nach dem Start vermutlich in einer Schleife neu starten („Bootloop“).

Um das zu beheben, öffne einmalig das Terminal in ZimaOS (oder verbinde dich per SSH) und führe diesen Befehl aus:

sudo chown -R 8983:8983 /media/RAID1/DATA/Papermerge/solr_data

Danach starte die App einmal neu, und alles läuft stabil.

Viel Erfolg bei der Installation!


Letzte Änderung: