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 ./consume is 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=skip skips 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.

  • Self-Hosting
  • Productivity
  • Docker