Self-hosted document management system running on Docker with PostgreSQL, Redis, and Gotenberg.
Path: /opt/paperless-ngx/
Port: 8000 (internal), routed through Caddy
| Container | Image | Purpose |
|---|---|---|
paperless-ngx |
ghcr.io/paperless-ngx/paperless-ngx |
Web application |
paperless-db |
postgres:17 |
PostgreSQL database |
paperless-broker |
redis:7 |
Redis cache/queue |
paperless-gotenberg |
gotenberg/gotenberg:8 |
Document conversion |
paperless-ngx_paperless -- internal service communicationproxy -- Caddy reverse proxyhttps://docs.autonomicllc.com (two-layer auth)http://paperless.tailc67641.ts.net (Paperless login only, Tailscale encrypted)docs.autonomicllc.com)Two layers:
Caddy basic_auth (browser prompt):
adminPaperlessAdmin2026!/opt/caddy/.htpasswd (bcrypt hash)Paperless login (after passing Caddy):
adminADMIN_PASS in /opt/paperless-ngx/.env (chmod 600)paperless.tailc67641.ts.net)Only Paperless login (no Caddy auth):
adminADMIN_PASS in /opt/paperless-ngx/.env (chmod 600)Paperless-ngx is configured to work with both routes:
| Setting | Value |
|---|---|
PAPERLESS_URL |
https://docs.autonomicllc.com |
PAPERLESS_CSRF_TRUSTED_ORIGINS |
https://docs.autonomicllc.com,http://paperless.tailc67641.ts.net |
SECURE_PROXY_SSL_HEADER |
HTTP_X_FORWARDED_PROTO,https |
This ensures Django recognizes CSRF tokens from both the public HTTPS route and the Tailscale HTTP route.
All credentials stored in service-specific .env files (chmod 600):
/opt/paperless-ngx/.env: DB_PASS, SECRET_KEY, ADMIN_PASS/opt/caddy/.htpasswd: basic_auth credentials for docs.autonomicllc.comThis instance shares its PostgreSQL and Redis with Wiki.js and Adminer:
paperless, wiki)