2026-07-06 22:09:36 +02:00
|
|
|
# Paperless-ngx service stack (PIHA) — UI + API + Postgres + Redis broker.
|
|
|
|
|
#
|
|
|
|
|
# KB module 2 (docs/kb/modules/02-paperless-service.md). Heavy OCR runs on a
|
|
|
|
|
# SEPARATE worker on SOLARIA (services/paperless-worker/, module 3) that shares
|
|
|
|
|
# this stack's Redis broker, Postgres and document storage (NFS export from
|
|
|
|
|
# PIHA). The built-in celery worker here stays at concurrency 1 as the slow
|
|
|
|
|
# fallback when SOLARIA is asleep — the stock image cannot disable it anyway.
|
|
|
|
|
#
|
|
|
|
|
# EXPOSURE: LAN/Tailscale ONLY (documents are sensitive — kb-00 rule #4).
|
|
|
|
|
# Every published port binds to LAN_BIND_IP (192.168.31.5), never 0.0.0.0.
|
|
|
|
|
# Users enter through npm@PIHA (paper.kapala.org vhost); the worker on SOLARIA
|
|
|
|
|
# reaches Redis/Postgres over the same fast LAN, NOT Tailscale.
|
|
|
|
|
services:
|
|
|
|
|
paperless:
|
|
|
|
|
# Multi-arch manifest includes linux/arm64 — runs natively on the Pi 5.
|
|
|
|
|
# The paperless-worker on SOLARIA MUST run the exact same tag (shared DB
|
|
|
|
|
# schema + task signatures); bump both together.
|
|
|
|
|
image: ghcr.io/paperless-ngx/paperless-ngx:2.14
|
|
|
|
|
container_name: paperless
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
depends_on:
|
|
|
|
|
db:
|
|
|
|
|
condition: service_healthy
|
|
|
|
|
broker:
|
|
|
|
|
condition: service_healthy
|
|
|
|
|
# Same trick as vikunja: pin the Forgejo OIDC issuer to npm on PIHA so
|
|
|
|
|
# discovery resolves over the LAN instead of flaky public DNS.
|
|
|
|
|
extra_hosts:
|
|
|
|
|
- "forgejo.kapala.org:192.168.31.5"
|
|
|
|
|
# Secrets via env_file only (vikunja pattern): PAPERLESS_SECRET_KEY,
|
|
|
|
|
# PAPERLESS_DBPASS, PAPERLESS_SOCIALACCOUNT_PROVIDERS (holds the OIDC
|
|
|
|
|
# client secret, hence the whole JSON lives in .env).
|
|
|
|
|
env_file:
|
|
|
|
|
- .env
|
|
|
|
|
environment:
|
feat(kb): configi Paperless/Nextcloud wg 9 decyzji — NC na PIHA, domeny kapala, Redis requirepass, backup SOLARIA, NC pin 34
Co zrobione:
- Nextcloud host = PIHA (always-on dla aktywnego uzycia), owner_node +
LAN_BIND_IP/TRUSTED_PROXIES w .env, README zaktualizowane
- Redis brokera Paperlessa: requirepass, PAPERLESS_REDIS_PASSWORD w .env
po obu stronach (PIHA + worker@SOLARIA), healthchecki z auth
- Domeny potwierdzone: paper.kapala.org, cloud.kapala.org (Cloudflare
DNS-only -> Tailscale PIHA, wildcard cert juz pokrywa) — udokumentowane,
nic nie utworzone
- Backup Paperlessa zatwierdzony: document_exporter + rsync/borg -> SOLARIA,
retencja 7/4/6, offsite jako future-note
- Nextcloud pin: 34-apache (zweryfikowany aktualny stable, endoflife.date)
- Whoosh fallback-worker: zaakceptowane bez zmian
- Porty/wylaczenie local login/sizing OCR-workera: przeniesione z "decyzji"
na "TODO przy deployu"
- DECYZJE-do-podjecia.md zaktualizowane: wszystko poza portami/loginem/
sizingiem przeniesione do "Rozstrzygniete"
Tylko edycja configow w repo — nic nie zdeployowane, zadne kontenery nie
byly ruszane, DNS/vhosty nie utworzone.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 16:15:35 +02:00
|
|
|
# Domain confirmed: paper.kapala.org (mesh-only, *.kapala.org wildcard
|
|
|
|
|
# cert already covers it — no new cert needed). DNS + npm vhost are
|
|
|
|
|
# deploy-time steps, see README Cutover checklist.
|
2026-07-06 22:09:36 +02:00
|
|
|
- PAPERLESS_URL=https://paper.kapala.org
|
|
|
|
|
- PAPERLESS_TIME_ZONE=Europe/Warsaw
|
feat(kb): configi Paperless/Nextcloud wg 9 decyzji — NC na PIHA, domeny kapala, Redis requirepass, backup SOLARIA, NC pin 34
Co zrobione:
- Nextcloud host = PIHA (always-on dla aktywnego uzycia), owner_node +
LAN_BIND_IP/TRUSTED_PROXIES w .env, README zaktualizowane
- Redis brokera Paperlessa: requirepass, PAPERLESS_REDIS_PASSWORD w .env
po obu stronach (PIHA + worker@SOLARIA), healthchecki z auth
- Domeny potwierdzone: paper.kapala.org, cloud.kapala.org (Cloudflare
DNS-only -> Tailscale PIHA, wildcard cert juz pokrywa) — udokumentowane,
nic nie utworzone
- Backup Paperlessa zatwierdzony: document_exporter + rsync/borg -> SOLARIA,
retencja 7/4/6, offsite jako future-note
- Nextcloud pin: 34-apache (zweryfikowany aktualny stable, endoflife.date)
- Whoosh fallback-worker: zaakceptowane bez zmian
- Porty/wylaczenie local login/sizing OCR-workera: przeniesione z "decyzji"
na "TODO przy deployu"
- DECYZJE-do-podjecia.md zaktualizowane: wszystko poza portami/loginem/
sizingiem przeniesione do "Rozstrzygniete"
Tylko edycja configow w repo — nic nie zdeployowane, zadne kontenery nie
byly ruszane, DNS/vhosty nie utworzone.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 16:15:35 +02:00
|
|
|
# Password-protected broker (requirepass) — see PAPERLESS_REDIS_PASSWORD
|
|
|
|
|
# in .env. MUST match the broker's --requirepass value below.
|
|
|
|
|
- PAPERLESS_REDIS=redis://:${PAPERLESS_REDIS_PASSWORD}@broker:6379
|
2026-07-06 22:09:36 +02:00
|
|
|
- PAPERLESS_DBHOST=db
|
|
|
|
|
- PAPERLESS_DBNAME=paperless
|
|
|
|
|
- PAPERLESS_DBUSER=paperless
|
|
|
|
|
# OCR: Polish + English. `pol` is downloaded into the container at boot.
|
|
|
|
|
- PAPERLESS_OCR_LANGUAGES=pol
|
|
|
|
|
- PAPERLESS_OCR_LANGUAGE=pol+eng
|
|
|
|
|
# Fallback-only OCR on the Pi: single worker, single thread. The real
|
|
|
|
|
# OCR muscle is paperless-worker@SOLARIA pulling from the same queue.
|
|
|
|
|
- PAPERLESS_TASK_WORKERS=1
|
|
|
|
|
- PAPERLESS_THREADS_PER_WORKER=1
|
|
|
|
|
- PAPERLESS_WEBSERVER_WORKERS=1
|
|
|
|
|
# Files on disk (media/, data/, consume/) are owned by this numeric UID.
|
|
|
|
|
# MUST equal USERMAP_UID/GID of paperless-worker@SOLARIA — the NFS export
|
|
|
|
|
# carries numeric IDs, not names. See services/paperless-worker/README.md.
|
|
|
|
|
- USERMAP_UID=1000
|
|
|
|
|
- USERMAP_GID=1000
|
|
|
|
|
# OIDC via Forgejo (django-allauth openid_connect). Provider JSON with
|
|
|
|
|
# client_id/secret comes from .env: PAPERLESS_SOCIALACCOUNT_PROVIDERS.
|
|
|
|
|
- PAPERLESS_APPS=allauth.socialaccount.providers.openid_connect
|
|
|
|
|
# First Forgejo login auto-creates the matching Paperless account.
|
|
|
|
|
- PAPERLESS_SOCIALACCOUNT_ALLOW_SIGNUPS=true
|
|
|
|
|
# No self-service local signups; local admin login stays for bootstrap.
|
feat(kb): configi Paperless/Nextcloud wg 9 decyzji — NC na PIHA, domeny kapala, Redis requirepass, backup SOLARIA, NC pin 34
Co zrobione:
- Nextcloud host = PIHA (always-on dla aktywnego uzycia), owner_node +
LAN_BIND_IP/TRUSTED_PROXIES w .env, README zaktualizowane
- Redis brokera Paperlessa: requirepass, PAPERLESS_REDIS_PASSWORD w .env
po obu stronach (PIHA + worker@SOLARIA), healthchecki z auth
- Domeny potwierdzone: paper.kapala.org, cloud.kapala.org (Cloudflare
DNS-only -> Tailscale PIHA, wildcard cert juz pokrywa) — udokumentowane,
nic nie utworzone
- Backup Paperlessa zatwierdzony: document_exporter + rsync/borg -> SOLARIA,
retencja 7/4/6, offsite jako future-note
- Nextcloud pin: 34-apache (zweryfikowany aktualny stable, endoflife.date)
- Whoosh fallback-worker: zaakceptowane bez zmian
- Porty/wylaczenie local login/sizing OCR-workera: przeniesione z "decyzji"
na "TODO przy deployu"
- DECYZJE-do-podjecia.md zaktualizowane: wszystko poza portami/loginem/
sizingiem przeniesione do "Rozstrzygniete"
Tylko edycja configow w repo — nic nie zdeployowane, zadne kontenery nie
byly ruszane, DNS/vhosty nie utworzone.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 16:15:35 +02:00
|
|
|
# TODO AT DEPLOY: after OIDC login is verified working, set
|
|
|
|
|
# PAPERLESS_DISABLE_REGULAR_LOGIN=true + PAPERLESS_REDIRECT_LOGIN_TO_SSO=true
|
|
|
|
|
# (decision already made — Vikunja runs both modes in parallel today too).
|
2026-07-06 22:09:36 +02:00
|
|
|
- PAPERLESS_ACCOUNT_ALLOW_SIGNUPS=false
|
|
|
|
|
volumes:
|
|
|
|
|
# Bind mounts under /opt/homelab/data (runtime path convention). These
|
|
|
|
|
# exact directories are NFS-exported to SOLARIA for the OCR worker —
|
|
|
|
|
# container paths (/usr/src/paperless/...) MUST be identical on both
|
|
|
|
|
# hosts because the DB and task payloads carry absolute paths.
|
|
|
|
|
- /opt/homelab/data/paperless/data:/usr/src/paperless/data
|
|
|
|
|
- /opt/homelab/data/paperless/media:/usr/src/paperless/media
|
|
|
|
|
- /opt/homelab/data/paperless/consume:/usr/src/paperless/consume
|
|
|
|
|
- /opt/homelab/data/paperless/export:/usr/src/paperless/export
|
|
|
|
|
ports:
|
|
|
|
|
# LAN-only bind; npm@PIHA proxies paper.kapala.org -> 192.168.31.5:8210.
|
feat(kb): configi Paperless/Nextcloud wg 9 decyzji — NC na PIHA, domeny kapala, Redis requirepass, backup SOLARIA, NC pin 34
Co zrobione:
- Nextcloud host = PIHA (always-on dla aktywnego uzycia), owner_node +
LAN_BIND_IP/TRUSTED_PROXIES w .env, README zaktualizowane
- Redis brokera Paperlessa: requirepass, PAPERLESS_REDIS_PASSWORD w .env
po obu stronach (PIHA + worker@SOLARIA), healthchecki z auth
- Domeny potwierdzone: paper.kapala.org, cloud.kapala.org (Cloudflare
DNS-only -> Tailscale PIHA, wildcard cert juz pokrywa) — udokumentowane,
nic nie utworzone
- Backup Paperlessa zatwierdzony: document_exporter + rsync/borg -> SOLARIA,
retencja 7/4/6, offsite jako future-note
- Nextcloud pin: 34-apache (zweryfikowany aktualny stable, endoflife.date)
- Whoosh fallback-worker: zaakceptowane bez zmian
- Porty/wylaczenie local login/sizing OCR-workera: przeniesione z "decyzji"
na "TODO przy deployu"
- DECYZJE-do-podjecia.md zaktualizowane: wszystko poza portami/loginem/
sizingiem przeniesione do "Rozstrzygniete"
Tylko edycja configow w repo — nic nie zdeployowane, zadne kontenery nie
byly ruszane, DNS/vhosty nie utworzone.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 16:15:35 +02:00
|
|
|
# TODO AT DEPLOY: port 8210 free per the 2026-06-30 inventory —
|
|
|
|
|
# reconfirm on the live host: ss -tlnp | grep 8210
|
2026-07-06 22:09:36 +02:00
|
|
|
- "${LAN_BIND_IP}:8210:8000"
|
|
|
|
|
healthcheck:
|
|
|
|
|
test: ["CMD", "curl", "-fs", "-S", "--max-time", "2", "http://localhost:8000"]
|
|
|
|
|
interval: 30s
|
|
|
|
|
timeout: 10s
|
|
|
|
|
retries: 5
|
|
|
|
|
start_period: 60s
|
|
|
|
|
|
|
|
|
|
db:
|
|
|
|
|
image: postgres:16-alpine
|
|
|
|
|
container_name: paperless-db
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
env_file:
|
|
|
|
|
- .env
|
|
|
|
|
environment:
|
|
|
|
|
- POSTGRES_DB=paperless
|
|
|
|
|
- POSTGRES_USER=paperless
|
|
|
|
|
- TZ=Europe/Warsaw
|
|
|
|
|
volumes:
|
|
|
|
|
- paperless_pgdata:/var/lib/postgresql/data
|
|
|
|
|
ports:
|
|
|
|
|
# Published on the LAN for paperless-worker@SOLARIA (192.168.31.70).
|
|
|
|
|
# 5433 is taken by kb-postgres. Postgres itself still enforces
|
|
|
|
|
# scram-sha-256 auth — the bind is exposure control, not the only lock.
|
|
|
|
|
- "${LAN_BIND_IP}:5434:5432"
|
|
|
|
|
healthcheck:
|
|
|
|
|
test: ["CMD-SHELL", "pg_isready -U paperless -d paperless"]
|
|
|
|
|
interval: 10s
|
|
|
|
|
timeout: 5s
|
|
|
|
|
retries: 5
|
|
|
|
|
|
|
|
|
|
broker:
|
|
|
|
|
image: redis:7-alpine
|
|
|
|
|
container_name: paperless-broker
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
# AOF persistence is REQUIRED: when SOLARIA is offline, queued OCR tasks
|
|
|
|
|
# (up to the 70k-attachment backlog) live only in this Redis. Without AOF a
|
|
|
|
|
# broker restart would silently drop the queue — violating the "zero lost
|
|
|
|
|
# tasks" criterion of module 3. Do NOT set maxmemory/eviction here.
|
feat(kb): configi Paperless/Nextcloud wg 9 decyzji — NC na PIHA, domeny kapala, Redis requirepass, backup SOLARIA, NC pin 34
Co zrobione:
- Nextcloud host = PIHA (always-on dla aktywnego uzycia), owner_node +
LAN_BIND_IP/TRUSTED_PROXIES w .env, README zaktualizowane
- Redis brokera Paperlessa: requirepass, PAPERLESS_REDIS_PASSWORD w .env
po obu stronach (PIHA + worker@SOLARIA), healthchecki z auth
- Domeny potwierdzone: paper.kapala.org, cloud.kapala.org (Cloudflare
DNS-only -> Tailscale PIHA, wildcard cert juz pokrywa) — udokumentowane,
nic nie utworzone
- Backup Paperlessa zatwierdzony: document_exporter + rsync/borg -> SOLARIA,
retencja 7/4/6, offsite jako future-note
- Nextcloud pin: 34-apache (zweryfikowany aktualny stable, endoflife.date)
- Whoosh fallback-worker: zaakceptowane bez zmian
- Porty/wylaczenie local login/sizing OCR-workera: przeniesione z "decyzji"
na "TODO przy deployu"
- DECYZJE-do-podjecia.md zaktualizowane: wszystko poza portami/loginem/
sizingiem przeniesione do "Rozstrzygniete"
Tylko edycja configow w repo — nic nie zdeployowane, zadne kontenery nie
byly ruszane, DNS/vhosty nie utworzone.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 16:15:35 +02:00
|
|
|
# requirepass: broker is bound to the LAN interface (trusted home network,
|
|
|
|
|
# but still reachable by anything on that LAN) — password auth decided
|
|
|
|
|
# over relying on the bind alone. Same value MUST be set as
|
|
|
|
|
# PAPERLESS_REDIS_PASSWORD in .env on both PIHA (this file) and
|
|
|
|
|
# paperless-worker@SOLARIA.
|
|
|
|
|
command: redis-server --appendonly yes --requirepass ${PAPERLESS_REDIS_PASSWORD}
|
2026-07-06 22:09:36 +02:00
|
|
|
volumes:
|
|
|
|
|
- paperless_redisdata:/data
|
|
|
|
|
ports:
|
|
|
|
|
# LAN-only bind for paperless-worker@SOLARIA. 6379 is taken by
|
|
|
|
|
# agent-system-redis.
|
feat(kb): configi Paperless/Nextcloud wg 9 decyzji — NC na PIHA, domeny kapala, Redis requirepass, backup SOLARIA, NC pin 34
Co zrobione:
- Nextcloud host = PIHA (always-on dla aktywnego uzycia), owner_node +
LAN_BIND_IP/TRUSTED_PROXIES w .env, README zaktualizowane
- Redis brokera Paperlessa: requirepass, PAPERLESS_REDIS_PASSWORD w .env
po obu stronach (PIHA + worker@SOLARIA), healthchecki z auth
- Domeny potwierdzone: paper.kapala.org, cloud.kapala.org (Cloudflare
DNS-only -> Tailscale PIHA, wildcard cert juz pokrywa) — udokumentowane,
nic nie utworzone
- Backup Paperlessa zatwierdzony: document_exporter + rsync/borg -> SOLARIA,
retencja 7/4/6, offsite jako future-note
- Nextcloud pin: 34-apache (zweryfikowany aktualny stable, endoflife.date)
- Whoosh fallback-worker: zaakceptowane bez zmian
- Porty/wylaczenie local login/sizing OCR-workera: przeniesione z "decyzji"
na "TODO przy deployu"
- DECYZJE-do-podjecia.md zaktualizowane: wszystko poza portami/loginem/
sizingiem przeniesione do "Rozstrzygniete"
Tylko edycja configow w repo — nic nie zdeployowane, zadne kontenery nie
byly ruszane, DNS/vhosty nie utworzone.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 16:15:35 +02:00
|
|
|
# TODO AT DEPLOY: port 6380 free per the 2026-06-30 inventory —
|
|
|
|
|
# reconfirm on the live host: ss -tlnp | grep 6380
|
2026-07-06 22:09:36 +02:00
|
|
|
- "${LAN_BIND_IP}:6380:6379"
|
|
|
|
|
healthcheck:
|
feat(kb): configi Paperless/Nextcloud wg 9 decyzji — NC na PIHA, domeny kapala, Redis requirepass, backup SOLARIA, NC pin 34
Co zrobione:
- Nextcloud host = PIHA (always-on dla aktywnego uzycia), owner_node +
LAN_BIND_IP/TRUSTED_PROXIES w .env, README zaktualizowane
- Redis brokera Paperlessa: requirepass, PAPERLESS_REDIS_PASSWORD w .env
po obu stronach (PIHA + worker@SOLARIA), healthchecki z auth
- Domeny potwierdzone: paper.kapala.org, cloud.kapala.org (Cloudflare
DNS-only -> Tailscale PIHA, wildcard cert juz pokrywa) — udokumentowane,
nic nie utworzone
- Backup Paperlessa zatwierdzony: document_exporter + rsync/borg -> SOLARIA,
retencja 7/4/6, offsite jako future-note
- Nextcloud pin: 34-apache (zweryfikowany aktualny stable, endoflife.date)
- Whoosh fallback-worker: zaakceptowane bez zmian
- Porty/wylaczenie local login/sizing OCR-workera: przeniesione z "decyzji"
na "TODO przy deployu"
- DECYZJE-do-podjecia.md zaktualizowane: wszystko poza portami/loginem/
sizingiem przeniesione do "Rozstrzygniete"
Tylko edycja configow w repo — nic nie zdeployowane, zadne kontenery nie
byly ruszane, DNS/vhosty nie utworzone.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 16:15:35 +02:00
|
|
|
test: ["CMD", "redis-cli", "-a", "${PAPERLESS_REDIS_PASSWORD}", "--no-auth-warning", "ping"]
|
2026-07-06 22:09:36 +02:00
|
|
|
interval: 10s
|
|
|
|
|
timeout: 5s
|
|
|
|
|
retries: 5
|
|
|
|
|
|
|
|
|
|
volumes:
|
|
|
|
|
# DB + broker state are host-local (NOT part of the NFS export). Document
|
|
|
|
|
# storage above is bind-mounted, not a named volume, because it doubles as
|
|
|
|
|
# the NFS export root for the SOLARIA worker.
|
|
|
|
|
paperless_pgdata:
|
|
|
|
|
paperless_redisdata:
|