paperless-ngx: kein extraEnv - PAPERLESS_LOGGING_DIR laesst sich nicht setzen #112

Closed
opened 2026-10-12 01:22:34 +02:00 by jlab-bot · 0 comments
Member

Der Chart paperless-ngx bietet keine Moeglichkeit, eine beliebige PAPERLESS_*-Variable zu setzen. Konkret fehlt PAPERLESS_LOGGING_DIR, und das kostet in cluster-config gerade 45 Prozent des Anwendungsprotokolls.

Der Anlass, gemessen am 11.10.2026

Alle drei Paperless-Instanzen (paperless-jk, paperless-cmk, paperless-ngx-tb) protokollieren massenhaft Tracebacks als WARNING ueber celery.redirected:

--- Logging error ---
  File "/usr/local/lib/python3.14/site-packages/concurrent_log_handler/__init__.py", line 477, in emit
    self.handleError(record)
Traceback (most recent call last):
  ...
RuntimeError: Cannot acquire lock after 20 attempts

Von 3000 Protokollzeilen tragen 1348 ein WARNING oder ERROR — 45 Prozent. Dahinter stehen 37 Fehlversuche, jeder mit einem Traceback ueber rund 30 Frames. Gezaehlt in allen drei Instanzen, gleichzeitig und mit identischer Verteilung (45 %, 50 %, 50 %).

Die Ursache liegt nicht in paperless, sondern im Speicher darunter. Das Datenverzeichnis /usr/src/paperless/data liegt auf einem RWX-Volume, das Longhorn per NFS ueber einen Share-Manager ausliefert (Longhorn spec.accessMode: rwx, PV ReadWriteMany, Share-Manager-Pod vorhanden). Dort schreibt paperless sein Protokoll mit dem concurrent_log_handler, und der nimmt vor jedem Schreib- und Rotationsvorgang eine Sperrdatei. Dateisperren ueber NFS sind unzuverlassig — daher die Zeitueberschreitung nach 20 Versuchen.

Das ist kein Zustand von heute Nacht. Die Upgrade-Fenster aus cluster-config #318 haben es nur verstaerkt, weil jedes Paperless-Volume gerade degraded ist und sein replicaModeMap ein ERR enthaelt — langsamerer Unterbau, mehr Sperrfehler. Der Mechanismus bleibt auch danach.

Was der Chart heute hergibt

Geprueft gegen die eingesetzte Fassung 12.2.0+up3.2.1 (helm show values): Die Werte-Schnittstelle hat acht Bloecke auf oberster Ebene —

scaleDown  secrets  ingress  paperless  smbConnection  oidc  valkeySubchart  valkey

— und darin keinen Logging-Schluessel und keine freie Env-Map. PAPERLESS_LOGGING_DIR ist damit von aussen nicht erreichbar.

Vorschlag

Bevorzugt: ein generisches extraEnv. Paperless kennt rund 80 Umgebungsvariablen, der Chart bildet eine Handvoll davon ab. Jede weitere einzeln nachzuziehen bedeutet fuer jede neue Einstellung eine Chart-Fassung; eine freie Map loest die ganze Klasse auf einmal.

# values.yaml
paperless:
  extraEnv: {}
    # PAPERLESS_LOGGING_DIR: /tmp/paperless-log
# im Deployment/StatefulSet, nach den bestehenden env-Eintraegen
{{- range $k, $v := .Values.paperless.extraEnv }}
- name: {{ $k }}
  value: {{ $v | quote }}
{{- end }}

Die Reihenfolge ist dabei nicht beliebig: Die Schleife gehoert hinter die festen Eintraege, damit eine Uebersteuerung auch greift — bei doppelten name-Eintraegen gewinnt der letzte. Das ist dieselbe Mechanik, die in cluster-config beim Homarr-Chart fuer ENABLE_KUBERNETES benutzt wird.

Alternative: ein eigener Schluessel, etwa paperless.logging.dir. Loest diesen Fall, aber nicht den naechsten.

Ein neues Volume braucht es nicht. Der Pod hat bereits ein emptyDir an /tmp gemountet; ein Pfad darunter genuegt als Ziel. Dass das Protokoll dann einen Pod-Neustart nicht ueberlebt, ist hier kein Verlust — paperless schreibt ohnehin zusaetzlich nach stdout, und genau das liest kubectl logs.

Was NICHT in diesen Chart gehoert

Die Frage, warum das Datenvolume ueberhaupt RWX ist, obwohl es genau einen Verbraucher hat: Das PVC fordert ReadWriteOnce, bereitgestellt wurde ReadWriteMany. RWO wuerde Share-Manager, NFS und die bekannte RWX-Haengergefahr auf einen Schlag loswerden — aber das ist eine Entscheidung in cluster-config und bedeutet, das Volume neu anzulegen. Hier geht es nur darum, dass der Chart die Variable ueberhaupt setzen kann.

Nebenbefund aus demselben Protokoll

Zweimal pikepdf._core.PdfError: unable to find trailer dictionary while recovering damaged file, gefolgt von documents.consumer.ConsumerError auf eine bestimmte …scan….pdf. Ein beschaedigter Scan, der im Consume-Verzeichnis liegt und bei jedem Durchlauf erneut versucht wird — nichts, was den Chart betrifft, aber es gehoert in cluster-config aufgeraeumt.

Kann mit #110 (Bump auf paperless 3.3.0) zusammen gehen.

Der Chart `paperless-ngx` bietet keine Moeglichkeit, eine beliebige `PAPERLESS_*`-Variable zu setzen. Konkret fehlt `PAPERLESS_LOGGING_DIR`, und das kostet in `cluster-config` gerade 45 Prozent des Anwendungsprotokolls. ## Der Anlass, gemessen am 11.10.2026 Alle drei Paperless-Instanzen (`paperless-jk`, `paperless-cmk`, `paperless-ngx-tb`) protokollieren massenhaft Tracebacks als `WARNING` ueber `celery.redirected`: ``` --- Logging error --- File "/usr/local/lib/python3.14/site-packages/concurrent_log_handler/__init__.py", line 477, in emit self.handleError(record) Traceback (most recent call last): ... RuntimeError: Cannot acquire lock after 20 attempts ``` Von 3000 Protokollzeilen tragen **1348** ein `WARNING` oder `ERROR` — **45 Prozent**. Dahinter stehen 37 Fehlversuche, jeder mit einem Traceback ueber rund 30 Frames. Gezaehlt in allen drei Instanzen, gleichzeitig und mit identischer Verteilung (45 %, 50 %, 50 %). **Die Ursache liegt nicht in paperless, sondern im Speicher darunter.** Das Datenverzeichnis `/usr/src/paperless/data` liegt auf einem **RWX-Volume, das Longhorn per NFS ueber einen Share-Manager ausliefert** (Longhorn `spec.accessMode: rwx`, PV `ReadWriteMany`, Share-Manager-Pod vorhanden). Dort schreibt paperless sein Protokoll mit dem `concurrent_log_handler`, und der nimmt vor jedem Schreib- und Rotationsvorgang eine Sperrdatei. Dateisperren ueber NFS sind unzuverlassig — daher die Zeitueberschreitung nach 20 Versuchen. Das ist kein Zustand von heute Nacht. Die Upgrade-Fenster aus `cluster-config` #318 haben es nur **verstaerkt**, weil jedes Paperless-Volume gerade `degraded` ist und sein `replicaModeMap` ein `ERR` enthaelt — langsamerer Unterbau, mehr Sperrfehler. Der Mechanismus bleibt auch danach. ## Was der Chart heute hergibt Geprueft gegen die eingesetzte Fassung **12.2.0+up3.2.1** (`helm show values`): Die Werte-Schnittstelle hat acht Bloecke auf oberster Ebene — ``` scaleDown secrets ingress paperless smbConnection oidc valkeySubchart valkey ``` — und darin **keinen Logging-Schluessel und keine freie Env-Map**. `PAPERLESS_LOGGING_DIR` ist damit von aussen nicht erreichbar. ## Vorschlag **Bevorzugt: ein generisches `extraEnv`.** Paperless kennt rund 80 Umgebungsvariablen, der Chart bildet eine Handvoll davon ab. Jede weitere einzeln nachzuziehen bedeutet fuer jede neue Einstellung eine Chart-Fassung; eine freie Map loest die ganze Klasse auf einmal. ```yaml # values.yaml paperless: extraEnv: {} # PAPERLESS_LOGGING_DIR: /tmp/paperless-log ``` ```yaml # im Deployment/StatefulSet, nach den bestehenden env-Eintraegen {{- range $k, $v := .Values.paperless.extraEnv }} - name: {{ $k }} value: {{ $v | quote }} {{- end }} ``` Die Reihenfolge ist dabei nicht beliebig: Die Schleife gehoert **hinter** die festen Eintraege, damit eine Uebersteuerung auch greift — bei doppelten `name`-Eintraegen gewinnt der letzte. Das ist dieselbe Mechanik, die in `cluster-config` beim Homarr-Chart fuer `ENABLE_KUBERNETES` benutzt wird. **Alternative: ein eigener Schluessel**, etwa `paperless.logging.dir`. Loest diesen Fall, aber nicht den naechsten. **Ein neues Volume braucht es nicht.** Der Pod hat bereits ein `emptyDir` an `/tmp` gemountet; ein Pfad darunter genuegt als Ziel. Dass das Protokoll dann einen Pod-Neustart nicht ueberlebt, ist hier kein Verlust — paperless schreibt ohnehin zusaetzlich nach stdout, und genau das liest `kubectl logs`. ## Was NICHT in diesen Chart gehoert Die Frage, warum das Datenvolume ueberhaupt RWX ist, obwohl es genau einen Verbraucher hat: Das PVC fordert `ReadWriteOnce`, bereitgestellt wurde `ReadWriteMany`. RWO wuerde Share-Manager, NFS und die bekannte RWX-Haengergefahr auf einen Schlag loswerden — aber das ist eine Entscheidung in `cluster-config` und bedeutet, das Volume neu anzulegen. Hier geht es nur darum, dass der Chart die Variable ueberhaupt setzen kann. ## Nebenbefund aus demselben Protokoll Zweimal `pikepdf._core.PdfError: unable to find trailer dictionary while recovering damaged file`, gefolgt von `documents.consumer.ConsumerError` auf eine bestimmte `…scan….pdf`. Ein beschaedigter Scan, der im Consume-Verzeichnis liegt und bei jedem Durchlauf erneut versucht wird — nichts, was den Chart betrifft, aber es gehoert in `cluster-config` aufgeraeumt. Kann mit #110 (Bump auf paperless 3.3.0) zusammen gehen.
jlab-bot added the inhouse-chart label 2026-10-12 01:22:34 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: jlab-cluster/helm-charts#112