Paperless-ngx turns piles of paper and PDF attachments into a searchable archive. Scan or upload a document, and it runs OCR (text recognition), stores a searchable PDF/A, and automatically assigns tags, correspondents and document types based on what it learns from you. Finding last year’s electricity bill becomes a two-second search. It runs well on a small VPS with Docker.
Requirements
- 2 vCPU and 2–4 GB RAM. OCR is CPU-intensive during imports, and idles lightly afterwards.
- Storage for documents. Most archives are a few GB.
- Docker and Docker Compose. See install Docker.
Your documents will include sensitive personal and financial data, so plan security and backups from the start.
Install with Docker Compose
The project provides ready-made compose files (PostgreSQL or MariaDB variants, with optional Tika/Gotenberg for Office documents and emails). An outline with PostgreSQL:
# /opt/paperless/compose.yaml (outline – see the official compose files)
services:
broker:
image: docker.io/library/redis:7
restart: unless-stopped
volumes: [redisdata:/data]
db:
image: docker.io/library/postgres:16
restart: unless-stopped
environment:
POSTGRES_DB: paperless
POSTGRES_USER: paperless
POSTGRES_PASSWORD: change-me-db
volumes: [pgdata:/var/lib/postgresql/data]
webserver:
image: ghcr.io/paperless-ngx/paperless-ngx:latest
restart: unless-stopped
depends_on: [db, broker]
ports:
- "127.0.0.1:8000:8000"
environment:
PAPERLESS_REDIS: redis://broker:6379
PAPERLESS_DBHOST: db
PAPERLESS_DBPASS: change-me-db
PAPERLESS_URL: https://docs.example.com
PAPERLESS_SECRET_KEY: change-me-long-random
PAPERLESS_OCR_LANGUAGE: eng
PAPERLESS_OCR_LANGUAGES: deu fra # extra languages to install
PAPERLESS_TIME_ZONE: Etc/UTC
volumes:
- ./data:/usr/src/paperless/data
- ./media:/usr/src/paperless/media
- ./export:/usr/src/paperless/export
- ./consume:/usr/src/paperless/consume
volumes:
pgdata:
redisdata:
cd /opt/paperless && docker compose up -d
docker compose run --rm webserver createsuperuser
Generate the secret key with openssl rand -base64 48.
HTTPS
server {
server_name docs.example.com;
client_max_body_size 100M;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# listen 443 ssl; certbot --nginx -d docs.example.com
}
PAPERLESS_URL must match the public URL. See Nginx reverse proxy and Let’s Encrypt.
Getting documents in
- Web upload: drag and drop PDFs and images in the UI.
- Consume folder: anything placed in
./consumeis imported automatically. Sync it from a scanner, Syncthing, SFTP or a network share. See Syncthing. - Email: configure Mail accounts and rules (IMAP) to fetch attachments, such as invoices sent to a dedicated address.
- Mobile apps (third-party) and scanning apps that upload via the REST API.
Many scanners can “scan to SFTP” or to a folder. Point that at the consume directory.
Let it organise for you
- Create tags (e.g.
tax-2026,insurance), correspondents (companies and people) and document types (invoice, contract, letter). - Set matching to Auto. Paperless learns from your manual assignments and assigns new documents automatically.
- Workflows apply rules on import (e.g. everything from the “invoices” mail rule gets tagged
invoice). - Custom fields store amounts, due dates or contract numbers.
Full-text search covers the OCR text of every document.
OCR tips
- Install the languages you need (
PAPERLESS_OCR_LANGUAGES) and set the default language. - Scan at 300 dpi in greyscale. That’s good for OCR, and keeps files small.
PAPERLESS_OCR_MODE=skipskips OCR for PDFs that already contain text.
Security
- HTTPS only, strong passwords, and 2FA (supported in recent versions).
- Consider access only via VPN for maximum privacy. See Tailscale.
- Restrict document permissions per user and group if several people use it.
- Keep it updated. See updating self-hosted apps.
Backups (essential)
Use the built-in document exporter. It writes all documents plus metadata in a portable format:
docker compose exec -T webserver document_exporter ../export
Then copy ./export (and ideally a database dump) off-server, encrypted. Schedule it daily. See GPG encryption and backup strategy. Keep your original paper for documents with legal requirements.
Quick reference
| Task | Command / setting |
|---|---|
| Start | docker compose up -d |
| Create admin | docker compose run --rm webserver createsuperuser |
| Public URL | PAPERLESS_URL |
| Auto-import | ./consume folder, mail rules |
| OCR languages | PAPERLESS_OCR_LANGUAGES |
| Export / backup | document_exporter ../export |
Related: Nextcloud and Docker security.