Paperless-ngx
Paperless-ngx is a document management
system that scans, OCRs, indexes, and archives paper documents. The HelmForge
chart runs the official ghcr.io/paperless-ngx/paperless-ngx image 3.3.2
with bundled PostgreSQL and Valkey subcharts, or external services.
Paperless-ngx is published with experimental maturity. Back up the database and media volume and verify restores before relying on it for important documents.
Key features
- Bundled HelmForge PostgreSQL
2.0.5and Valkey2.0.4subcharts, or SQLite for small installs - External PostgreSQL and Valkey/Redis with existing Secret support
- Separate PVCs for data, media, consume, and export, each with
existingClaim - Optional Apache Tika and Gotenberg for office documents and emails
- Superuser bootstrap with a generated password stored in a Secret
- Ingress, Gateway API HTTPRoute, and dual-stack Service controls
- External Secrets Operator integration for the external database password
- Rootless restricted security context with no service account token
Install
helm repo add helmforge https://repo.helmforge.dev
helm repo update
helm install paperless-ngx helmforge/paperless-ngx \
--namespace paperless --create-namespace
Read the generated superuser password:
kubectl -n paperless get secret paperless-ngx-admin -o jsonpath='{.data.admin-password}' | base64 -d; echo
A typical install sets the public URL, time zone, OCR language, and ingress:
paperless:
url: https://paperless.example.com
timeZone: Europe/Berlin
ocrLanguage: deu+eng
ingress:
enabled: true
ingressClassName: traefik
hosts:
- host: paperless.example.com
paths:
- path: /
pathType: Prefix
Set paperless.url, or an ingress or gateway hostname it can be derived from. Logins through a hostname that does not
match fail CSRF checks.
Replica model
The web server, task worker, scheduler, and consumer run in one container, and
the data volume holds the search index and classifier. replicaCount is
therefore limited to 0 or 1, and the default Recreate strategy ensures
two pods never share the volumes.
Database and broker
database.mode: auto uses external PostgreSQL when database.external.host is
set, otherwise the PostgreSQL subchart when postgresql.enabled=true, otherwise
SQLite in the data volume. Driver settings such as TLS go into
database.options (PAPERLESS_DB_OPTIONS).
database:
mode: external
external:
host: postgres.example.internal
existingSecret: paperless-db
options: 'sslmode=require'
postgresql:
enabled: false
valkey:
enabled: false
external:
host: valkey.example.internal
existingSecret: paperless-valkey
The Valkey password is embedded in the PAPERLESS_REDIS URL, so a supplied
password must be URL-safe (no @, :, /, or %). Passwords generated by the
Valkey subchart are alphanumeric.
Volumes
| Volume | Mount path | Default | Content |
|---|---|---|---|
data |
/usr/src/paperless/data |
PVC, 2Gi | Search index, classifier, SQLite, logs |
media |
/usr/src/paperless/media |
PVC, 10Gi | Original and archived documents |
consume |
/usr/src/paperless/consume |
emptyDir | Watched input folder |
export |
/usr/src/paperless/export |
emptyDir | document_exporter output |
PVCs carry helm.sh/resource-policy: keep and survive helm uninstall. Point
persistence.consume.existingClaim at a shared scanner volume to ingest scans.
NFS and SMB do not deliver inotify events, so set
paperless.consumer.pollingInterval for those filesystems.
Office documents and emails
Enable Tika and Gotenberg together to process Office files and emails:
tika:
enabled: true
gotenberg:
enabled: true
Gotenberg runs with JavaScript disabled and only local files allowed, matching the upstream compose files, so tracking pixels and scripts in emails are not fetched.
Gateway API
gateway:
enabled: true
parentRefs:
- name: shared-gateway
namespace: gateway-system
hostnames:
- paperless.example.com
GitOps renderers
The chart generates the secret key and superuser password once and reuses them
through lookup. Renderers such as Argo CD run without cluster access, so the
values are regenerated on every render and the pod restarts on every sync.
Provide the secrets yourself in that case:
paperless:
existingSecret: paperless-app # key: secret-key
admin:
existingSecret: paperless-admin # key: admin-password
Security and operations
Paperless-ngx runs as UID/GID 1000 with runAsNonRoot, fsGroup,
RuntimeDefault seccomp, and all capabilities dropped. A startup warning about
volumes not being owned by the current user is expected: volumes are root-owned
with group write through fsGroup. The image ships OCR languages eng, deu,
ita, spa, and fra; installing more through PAPERLESS_OCR_LANGUAGES
requires running as root.
Back up the database and media volume before upgrades, and keep the secret key
stable to preserve sessions and tokens. document_exporter writes documents and
metadata to the export directory.
Values overview
| Value | Default | Purpose |
|---|---|---|
replicaCount |
1 |
0 or 1 |
image.repository |
ghcr.io/paperless-ngx/paperless-ngx |
Application image |
image.tag |
3.3.2 |
Application image tag |
paperless.url |
empty | Public URL, derived from ingress/gateway host |
paperless.timeZone |
UTC |
Time zone |
paperless.ocrLanguage |
eng |
Default OCR language, for example deu+eng |
paperless.admin.enabled |
true |
Create a superuser on startup |
paperless.consumer.pollingInterval |
0 |
Poll interval in seconds; 0 uses inotify |
database.mode |
auto |
auto, external, postgresql, or sqlite |
postgresql.enabled |
true |
Deploy the PostgreSQL subchart |
valkey.enabled |
true |
Deploy the Valkey subchart |
persistence.media.size |
10Gi |
Document storage size |
tika.enabled, gotenberg.enabled |
false |
Office document and email processing |
ingress.enabled |
false |
Ingress |
gateway.enabled |
false |
Gateway API HTTPRoute |
externalSecrets.enabled |
false |
ExternalSecret for the external database |
The complete validated contract is in
values.yaml
and
values.schema.json.