Paperless-ngx
Paperless-ngx runs in the paperless namespace. It uses the shared PostgreSQL
service in the database namespace and Valkey for its task queue. The document
library, exports, and consume folder are stored on the local-path-retain
volume. The PVC size is fixed at 50 GiB because this storage class does not
support volume expansion.
The local route is https://papers.workstation.internal; the public route is
https://papers.forust.xyz. Both use TLS. Paperless keeps its own login and
password authentication. OCR is configured for Russian and English documents.
Keep papers.forust.xyz in the existing Cloudflare DDNS DOMAINS setting so
the public record follows the workstation address.
Compose alternative
compose.yaml is an alternative to the active Kubernetes deployment. Do not
run both at the same time: they use the same Paperless database and route
names, but have separate document volumes.
The Compose variant uses the shared Compose PostgreSQL service on the
homelab-database Docker network. It does not start a PostgreSQL container.
The shared Compose database must be running and must have the paperless
database and role. Set PAPERLESS_DBPASS to the same password as
PAPERLESS_DB_PASSWORD in the shared PostgreSQL configuration.
To prepare and start the Compose variant:
cp paperless/.env.example paperless/.env
cd paperless
docker compose -f compose.yaml config --quiet
docker compose -f compose.yaml up -d
Create unique values for PAPERLESS_SECRET_KEY and
PAPERLESS_ADMIN_PASSWORD in .env. This directory has no Compose active
marker, so the repository deploy workflow does not start this alternative.
Stop the Kubernetes Paperless deployment before switching to Compose. Back up
and migrate the media files as well as the database; the Compose named volumes
are separate from the Kubernetes PVC.
Prepare the secret
Create k8s/secrets.yaml on the workstation from
k8s/secrets.yaml.example. Set a unique random PAPERLESS_SECRET_KEY, a long
PAPERLESS_ADMIN_PASSWORD, and PAPERLESS_DB_PASSWORD.
Add the same PAPERLESS_DB_PASSWORD value to the local
postgres/k8s/secrets.yaml file. Keep both secret files out of Git. The
database bootstrap Job creates the paperless role and database from the
shared PostgreSQL secret. The job runs in the database namespace and needs
that namespace's existing postgres-shared-secrets Secret.
For example, generate a key with:
python3 -c 'import secrets; print(secrets.token_urlsafe(64))'
Then apply the secret before enabling the service:
kubectl apply -f paperless/k8s/namespace.yaml
kubectl apply -f postgres/k8s/secrets.yaml
kubectl apply -f paperless/k8s/secrets.yaml
The normal deploy workflow applies the remaining manifests when
paperless/k8s/active is present. Verify the rollout and ingress after deploy:
kubectl -n paperless rollout status deployment/paperless
kubectl -n paperless get pods,pvc,services
Back up the paperless-data PVC and the shared PostgreSQL database. The PVC
contains the originals, archived PDFs, and export/consume folders. Valkey has
no persistent volume; queued tasks are recreated after a restart.