What is Paperless-ngx?
Paperless-ngx is a document management system that scans, OCRs, indexes and archives your paper documents so you can search them like email. It is open source under the GPL-3.0 license and is the community-maintained successor to Paperless and Paperless-ng. It learns how to tag, file and date incoming documents automatically, and stores everything as searchable PDF/A.
Requirements
- A Linux server with 2 vCPU and 2 GB of RAM. OCR is CPU-heavy, so 4 GB and more cores speed up large imports.
- Docker Engine and Docker Compose v2.
- Disk space for originals plus archived PDF/A copies.
Step 1: Prepare the server
This guide assumes Ubuntu 24.04 with Docker installed. If you need Docker, see the official install guide. Create a project folder with the directories Paperless uses for import and export:
mkdir -p ~/paperless/{consume,export} && cd ~/paperless
id -u && id -g
Note your user ID and group ID. Paperless will run with them so you can drop files into consume without permission problems.
Step 2: Create the Docker Compose file
The official stack uses Postgres as the database and Redis (or Valkey) as the task broker. Save this as docker-compose.yml:
services:
broker:
image: docker.io/valkey/valkey:8-alpine
restart: unless-stopped
volumes:
- redisdata:/data
db:
image: docker.io/library/postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: paperless
POSTGRES_USER: paperless
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- pgdata:/var/lib/postgresql/data
webserver:
image: ghcr.io/paperless-ngx/paperless-ngx:latest
restart: unless-stopped
depends_on:
- db
- broker
ports:
- "8000:8000"
volumes:
- data:/usr/src/paperless/data
- media:/usr/src/paperless/media
- ./export:/usr/src/paperless/export
- ./consume:/usr/src/paperless/consume
environment:
PAPERLESS_REDIS: redis://broker:6379
PAPERLESS_DBHOST: db
PAPERLESS_DBENGINE: postgresql
PAPERLESS_DBPASS: ${POSTGRES_PASSWORD}
PAPERLESS_SECRET_KEY: ${PAPERLESS_SECRET_KEY}
PAPERLESS_URL: https://docs.example.com
PAPERLESS_TIME_ZONE: Europe/London
PAPERLESS_OCR_LANGUAGE: eng
USERMAP_UID: 1000
USERMAP_GID: 1000
volumes:
data:
media:
pgdata:
redisdata:
Create .env in the same folder:
POSTGRES_PASSWORD=CHANGE_ME
PAPERLESS_SECRET_KEY=CHANGE_ME
Generate each value with openssl rand -hex 32. Set USERMAP_UID and USERMAP_GID to the numbers from Step 1, and PAPERLESS_URL to the exact public URL you will use. For OCR in several languages, join codes with a plus sign, for example deu+eng. To pin a release instead of latest, use a version tag from the releases page.
Step 3: Start and open the app
docker compose up -d
docker compose run --rm webserver createsuperuser
The second command prompts for an admin username, email and password. Then open http://YOUR_SERVER_IP:8000 and sign in. To test the pipeline, copy a PDF into ~/paperless/consume: within a minute Paperless picks it up, runs OCR and shows it in the document list. You can also upload through the web UI or set up mail rules to fetch attachments from an inbox.
Step 4: Put it behind HTTPS
With Caddy on the host:
docs.example.com {
request_body {
max_size 200MB
}
reverse_proxy 127.0.0.1:8000
}
Make sure PAPERLESS_URL matches this domain exactly, including https://. The UI uses WebSockets for live upload status, which Caddy passes automatically. With Nginx Proxy Manager, enable "Websockets Support". Once HTTPS works, change the port mapping to "127.0.0.1:8000:8000".
Backups and upgrades
The most reliable backup is the built-in document exporter, which writes originals, archived PDFs and all metadata to the export folder:
docker compose exec -T webserver document_exporter ../export
Copy ~/paperless/export off-site afterwards, encrypted. Also keep your .env. The exporter output can be re-imported into a fresh install with document_importer.
To upgrade, back up first, read the release notes, then run:
docker compose pull && docker compose up -d
Database migrations run automatically on start.
Troubleshooting
- "CSRF verification failed" when logging in:
PAPERLESS_URLdoes not match the address in your browser. Fix it and recreate the container. - Files in
consumeare ignored: check permissions (the folder must be writable byUSERMAP_UID). On network shares, setPAPERLESS_CONSUMER_POLLING=30, because inotify events do not cross NFS or SMB. - OCR fails with a language error: the language code is not installed. Add it to
PAPERLESS_OCR_LANGUAGESso the container installs it on start. - Imports are slow: add CPU cores, or lower OCR work with
PAPERLESS_OCR_MODE=skipfor documents that already contain text.
Next steps
Create correspondents, document types and tags, train the automatic matching, add a third-party mobile app for scanning on the go, and schedule the exporter with cron.
Spotted something out of date? Tell us and we will update the guide.