Recipes
Self-host Paperless-ngx with a public URL
Deploy Paperless-ngx as a Docker Compose app and reach it from anywhere over HTTPS, without port forwarding or a static IP.
This deploys Paperless-ngx, a document management and OCR system, along with its Postgres and Redis dependencies, and exposes the web UI at a public HTTPS URL that Nethera assigns. For a full introduction to how Nethera works, see /docs.
Why self-host Paperless-ngx
The realistic alternative to this isn't "no document management," it's Paperless-ngx running on a home server or NAS that you can only reach on your LAN. That works fine at your desk, but it breaks the actual use case: scanning a receipt or ID at the point you need it, then pulling it up later from your phone, a client's office, or anywhere that isn't your home network. The usual fixes for that (port forwarding to a self-hosted box, or dropping the documents into Google Drive/Dropbox instead) either open a raw port on your home connection or hand tax records, contracts, and IDs to someone else's cloud. Deploying via Nethera keeps the documents on infrastructure you control and still gives you a URL that works from outside your network, without you configuring the router or trusting a third party with the files.
Requirements
- Nethera CLI (
neth) installed - A machine running the Nethera agent, reachable by the CLI
See /docs/quickstart for setup of both.
nethera.yml
appName: paperlessservices: web: image: ghcr.io/paperless-ngx/paperless-ngx:latest environment: PAPERLESS_REDIS: redis://redis:6379 PAPERLESS_DBHOST: db PAPERLESS_DBNAME: paperless PAPERLESS_DBUSER: paperless PAPERLESS_URL: ${NETHERA_PUBLIC_URL} PAPERLESS_ADMIN_USER: admin volumes: - paperless-data:/usr/src/paperless/data - paperless-media:/usr/src/paperless/media - paperless-export:/usr/src/paperless/export - /mnt/nethera/paperless/consume:/usr/src/paperless/consume depends_on: - db - redis nethera: public: 8000 # exposes container port 8000 (Paperless's web UI) at the public HTTPS URL auth: login # requires Nethera login before Paperless-ngx loads secrets: - PAPERLESS_SECRET_KEY - PAPERLESS_DBPASS - PAPERLESS_ADMIN_PASSWORD db: image: postgres:16-alpine environment: POSTGRES_DB: paperless POSTGRES_USER: paperless volumes: - paperless-db:/var/lib/postgresql/data nethera: secrets: - POSTGRES_PASSWORD redis: image: redis:7-alpine volumes: - paperless-redis:/data volumes: paperless-data: paperless-media: paperless-export: paperless-db: paperless-redis:Only web has public: 8000, so only the Paperless-ngx web UI is exposed through Nethera. Postgres and Redis stay internal to the Compose network.
Deploy
Initialize the app and set Paperless-ngx secrets:
$neth init$neth secrets set PAPERLESS_SECRET_KEY$neth secrets set PAPERLESS_DBPASS$neth secrets set POSTGRES_PASSWORD$neth secrets set PAPERLESS_ADMIN_PASSWORD$neth deployUse the same value for PAPERLESS_DBPASS and POSTGRES_PASSWORD, unless you also change the database/user setup.
neth init prepares the Nethera metadata for the app, including the generated app identifier and target machine selection.
Nethera injects NETHERA_PUBLIC_URL into the deployment env file, so Paperless-ngx gets the correct public URL during the first deploy.
Open and verify
Open the HTTPS endpoint printed by neth deploy. You'll be prompted for Nethera login before Paperless-ngx loads. Then log in to Paperless-ngx with the admin user configured in this recipe:
username: admin
password: the value you set with neth secrets set PAPERLESS_ADMIN_PASSWORDCheck that the UI loads correctly over the public URL before relying on it.
Data and config notes
/mnt/nethera/paperless/consumeis the drop folder on the machine running the Nethera agent: anything placed in it gets OCR'd and imported automatically.paperless-mediaholds the processed originals and thumbnails;paperless-dataholds the search index and app state. Back both up, not just the database.paperless-exportis where Paperless-ngx writes bulk exports if you run one; it's empty until you do.PAPERLESS_URLusesNETHERA_PUBLIC_URL, which Nethera injects automatically from the public endpoint.PAPERLESS_SECRET_KEY,PAPERLESS_DBPASS,POSTGRES_PASSWORD, andPAPERLESS_ADMIN_PASSWORDare stored as Nethera secrets and injected into the containers at deploy time.
Troubleshooting
CSRF or "Bad Request" errors on login. Usually means PAPERLESS_URL doesn't match the URL you're actually accessing. Check that it still uses ${NETHERA_PUBLIC_URL}.
web container restarts on first deploy. db and redis may not be ready yet when web starts, since depends_on here doesn't wait for a health check. Give it a minute and check web's logs; it should come up once Postgres is accepting connections.
Files dropped in consume aren't showing up. Confirm they're going into /mnt/nethera/paperless/consume on the machine running the Nethera agent, not a local folder on your development machine.
Paperless-ngx cannot connect to Postgres. Check that PAPERLESS_DBPASS and POSTGRES_PASSWORD were set to the same value, unless you intentionally changed the database setup.
FAQ
Can I access my Paperless-ngx instance from outside my home network?
Yes. The public: 8000 field maps the web UI to the HTTPS URL Nethera assigns, so it's reachable from anywhere, no port forwarding or dynamic DNS setup on your end.
Why not just use a VPN, like Tailscale or WireGuard?
A VPN works well if it's just you, or a small group who already have a client installed. Nethera's endpoint is a normal HTTPS link instead, useful once you want to share access without asking someone to install anything. auth: login still gates who's let through if you want that.
Why run Paperless-ngx myself instead of just scanning documents into Google Drive? Because the documents stay on infrastructure you control instead of a third party's cloud, while you still get the remote access that makes scanning-on-the-go useful in the first place, without opening a port on your home router to get it.
How do I change the domain after I've already deployed? Use Nethera-generated endpoint env vars for the default endpoint. Custom-domain support is documented separately when available.
Can I use auth: none instead?
Yes, if you want Paperless-ngx's own users to be the only access layer and you're comfortable with the Paperless login page being reachable by anyone with the URL. This recipe uses auth: login by default because document storage is usually sensitive.
Can I redeploy or update this without SSHing into the machine?
Yes, neth deploy from your project directory redeploys in place. If you're managing more than one machine, the same command and nethera.yml work whether you're targeting one or several, see fleet management for pairing multiple machines under one workspace.
Notes
- Back up
paperless-dataandpaperless-media, not just the Postgres volume; the search index and originals live outside the database. - Keep
PAPERLESS_SECRET_KEYstable. Changing or losing it later can break existing sessions and security-related state. - The consume folder is a host path at
/mnt/nethera/paperless/consume, so files must be placed there on the machine running the agent.