Paperless-ngx on Proxmox LXC: Build a Self-Hosted Document Archive That Works in 2026
Self-Hosting

Paperless-ngx on Proxmox LXC: Build a Self-Hosted Document Archive That Works in 2026

Ricardo Gil
August 4, 2026
9 min read
#Paperless-ngx #Proxmox #Self-Hosting #Home Lab

If you've got a pile of PDFs, scanned invoices, insurance docs, and tax records living in a random folder hierarchy on your NAS β€” or worse, in Google Drive β€” Paperless-ngx is the fix. It's an open-source document management system that ingests documents, runs OCR on everything, and makes the entire archive full-text searchable. It runs well on Proxmox LXC, and it's one of those services worth rebuilding first if your home lab ever burned down.

This guide covers the complete 2026 setup: LXC container, Docker Compose stack, storage passthrough, scanner integration, and a few production-level tweaks that the official docs gloss over.

What Is Paperless-ngx and Why Should You Self-Host It?

Paperless-ngx is a fork of Paperless and Paperless-ng that's actively maintained and genuinely production-ready. Drop a PDF in the consume folder β€” from a network scanner, email, or the mobile app β€” and within minutes it's OCR'd, tagged, assigned a correspondent, and searchable by full text.

The killer feature is the AI-assisted auto-tagging: you train it over time, and it starts classifying documents automatically. After a few hundred documents, the classifier is accurate enough that I rarely need to touch incoming docs manually.

Running Paperless-ngx in your Proxmox home lab instead of a cloud service means zero per-document fees, your documents never leave your network, and the archive survives any SaaS shutdown.

Prerequisites

Before you start, you need:

  • Proxmox VE 8.x or 9.x (see my Proxmox VE 9 upgrade guide if you haven't upgraded yet)
  • At least 2 vCPUs and 2 GB RAM for the LXC β€” 4 GB recommended for fast OCR
  • A storage location for the document archive (NAS, ZFS pool, or a dedicated SSD)
  • Optional but recommended: a network document scanner

Step 1: How Do I Create the Proxmox LXC Container?

Download the Ubuntu 22.04 LXC template if you haven't already:

bash
pveam update
pveam download local ubuntu-22.04-standard_22.04-1_amd64.tar.zst

Create the container. I use 2 vCPUs and 3 GB RAM β€” OCR is CPU-intensive when it first processes a backlog:

bash
pct create 110 local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst \
  --hostname paperless \
  --memory 3072 \
  --cores 2 \
  --net0 name=eth0,bridge=vmbr0,ip=dhcp \
  --storage local-lvm \
  --rootfs local-lvm:8 \
  --unprivileged 1 \
  --features nesting=1

The nesting=1 feature flag is required for Docker to run inside an unprivileged LXC container. Start it and grab the IP:

bash
pct start 110
pct exec 110 -- ip addr show eth0 | grep "inet "

Set a static IP through your router or OPNsense DHCP reservation. Assign something memorable β€” 192.168.x.110 works well.

Step 2: Install Docker Inside the LXC

bash
pct exec 110 -- bash -c "apt-get update && apt-get install -y ca-certificates curl gnupg"
pct exec 110 -- bash -c "install -m 0755 -d /etc/apt/keyrings && \
  curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg && \
  chmod a+r /etc/apt/keyrings/docker.gpg"
pct exec 110 -- bash -c 'echo \
  "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" > /etc/apt/sources.list.d/docker.list'
pct exec 110 -- bash -c "apt-get update && apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin"

Verify it works:

bash
pct exec 110 -- docker run --rm hello-world

Step 3: How Do I Set Up Storage Passthrough for the Document Archive?

Don't store your document archive inside the LXC rootfs β€” put it on a proper storage volume. I use a ZFS dataset on my main Proxmox node.

On the Proxmox host, create the dataset and directories:

bash
zfs create rpool/paperless
mkdir -p /rpool/paperless/{data,media,export,consume}
chown -R 1000:1000 /rpool/paperless

Bind-mount them into the LXC by adding to /etc/pve/lxc/110.conf:

code
mp0: /rpool/paperless,mp=/paperless

Restart the container:

bash
pct restart 110

Inside the LXC, verify the mount:

bash
pct exec 110 -- ls /paperless
# should show: consume  data  export  media

If you're storing documents on a NAS drive instead of a local ZFS pool, the Seagate IronWolf 4TB and WD Red Plus 4TB are both rated for NAS workloads and significantly more reliable than desktop drives under continuous write pressure. For a more budget-conscious option, a Samsung 870 EVO 2TB SSD as the archive drive gives you excellent random read speed when searching.

Step 4: Configure the Docker Compose Stack

Inside the LXC, create /opt/paperless/docker-compose.yml:

bash
mkdir -p /opt/paperless
cat > /opt/paperless/docker-compose.yml << 'EOF'
version: "3.4"

services:
  broker:
    image: docker.io/library/redis:7
    restart: unless-stopped
    volumes:
      - redisdata:/data

  db:
    image: docker.io/library/postgres:16
    restart: unless-stopped
    volumes:
      - pgdata:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: paperless
      POSTGRES_USER: paperless
      POSTGRES_PASSWORD: changeme_strong_password

  webserver:
    image: ghcr.io/paperless-ngx/paperless-ngx:latest
    restart: unless-stopped
    depends_on:
      - db
      - broker
    ports:
      - "8000:8000"
    volumes:
      - /paperless/data:/usr/src/paperless/data
      - /paperless/media:/usr/src/paperless/media
      - /paperless/export:/usr/src/paperless/export
      - /paperless/consume:/usr/src/paperless/consume
    environment:
      PAPERLESS_REDIS: redis://broker:6379
      PAPERLESS_DBHOST: db
      PAPERLESS_DBUSER: paperless
      PAPERLESS_DBPASS: changeme_strong_password
      PAPERLESS_OCR_LANGUAGE: eng
      PAPERLESS_SECRET_KEY: changeme_generate_with_openssl_rand_-hex_32
      PAPERLESS_TIME_ZONE: America/New_York
      PAPERLESS_URL: http://192.168.1.110:8000
      PAPERLESS_OCR_THREADS: 2
      PAPERLESS_CONSUMER_POLLING: 60
      PAPERLESS_TASK_WORKERS: 2
      PAPERLESS_THREADS_PER_WORKER: 1

volumes:
  pgdata:
  redisdata:
EOF

Adjust PAPERLESS_OCR_LANGUAGE for your document corpus β€” use eng+spa for English + Spanish.

Generate a real secret key:

bash
pct exec 110 -- bash -c "docker run --rm -it ghcr.io/paperless-ngx/paperless-ngx:latest python3 -c 'import secrets; print(secrets.token_hex(32))'"

Spin up the stack:

bash
pct exec 110 -- bash -c "cd /opt/paperless && docker compose up -d"

Create the admin user:

bash
pct exec 110 -- bash -c "cd /opt/paperless && docker compose exec webserver python3 manage.py createsuperuser"

Hit http://192.168.1.110:8000 in your browser and you should see the Paperless-ngx UI.

Step 5: How Do I Set Up Scanner Integration?

Network Scanners

If you have a network-capable scanner, point it at the consume directory directly or expose it via Samba:

bash
pct exec 110 -- bash -c "apt-get install -y samba"
cat >> /etc/samba/smb.conf << 'EOF'

[paperless-consume]
   path = /paperless/consume
   browseable = yes
   read only = no
   guest ok = no
   valid users = paperless
EOF
pct exec 110 -- bash -c "smbpasswd -a paperless && systemctl restart smbd"

For scanning hardware, the Fujitsu ScanSnap iX1600 is the gold standard for home office document scanning β€” duplex, 40ppm, and the companion app can push directly to a WiFi folder. The Canon imageFORMULA R40 is a solid mid-range pick if you're not ready to spend $400+. For lighter use, the Epson WorkForce ES-400 II handles typical home office volumes without complaints.

Mobile Scanning

Install the official Paperless-ngx mobile app (iOS/Android) or Paperless Mobile. Point it at your Paperless-ngx URL and admin credentials β€” you can snap a photo of a receipt and have it processed and tagged in under two minutes.

For remote access without opening ports, Cloudflare Tunnels in front of Paperless-ngx is the cleanest approach: zero exposed ports, free tier handles the traffic easily.

Step 6: How Does Auto-Classification Training Work?

Paperless-ngx's classifier needs documents to train on. Go to Admin β†’ Machine Learning β†’ Run trainer once you have 50+ documents ingested. After roughly 200 documents with properly assigned correspondents and tags, the auto-assignment accuracy becomes genuinely useful β€” I get around 90% accuracy on my setup.

Tag taxonomy matters. Keep it flat and broad rather than deep and specific: tax, insurance, medical, utilities, bank, receipts. Deep hierarchies defeat the classifier.

Step 7: Add HTTPS with Traefik

Don't run Paperless-ngx on HTTP in production, even on a local network. If you're already running Traefik on Proxmox LXC, add label-based routing to the compose file:

yaml
labels:
  - "traefik.enable=true"
  - "traefik.http.routers.paperless.rule=Host(`paperless.yourdomain.internal`)"
  - "traefik.http.routers.paperless.tls=true"
  - "traefik.http.routers.paperless.tls.certresolver=letsencrypt"
  - "traefik.http.services.paperless.loadbalancer.server.port=8000"

Update PAPERLESS_URL in your compose file to the HTTPS hostname and restart.

Backup Strategy

Your document archive is irreplaceable. Paperless-ngx has a built-in export command:

bash
docker compose exec webserver document_exporter /paperless/export

Add this to a cron job inside the LXC and sync the export directory to an external SSD or an offsite S3 bucket with rclone. Run nightly exports and sync them to a Samsung T7 Shield 2TB connected to a separate machine.

For the media directory (the actual document files), use Proxmox Backup Server or ZFS snapshot replication. The media directory plus a PostgreSQL dump is your full recovery set:

bash
docker compose exec db pg_dump -U paperless paperless > /paperless/export/paperless-db-$(date +%Y%m%d).sql

What Hardware Does Paperless-ngx Need?

On my home lab node (a Beelink GTi13 Ultra running Proxmox), the Paperless-ngx stack idles at roughly 180 MB RAM. During bulk OCR ingestion of a multi-page PDF, it spikes to 600–800 MB and pegs one CPU core. With 3 GB allocated and PAPERLESS_OCR_THREADS: 2, large batches finish without OOMing.

Anything running Proxmox comfortably handles Paperless-ngx as one LXC among many. A used Intel NUC 12 Pro or a refurbished Dell OptiPlex 7090 both have more than enough headroom to run Paperless alongside Immich, Jellyfin, and other services without breaking a sweat.

If you want to run the full stack plus ML-heavy auto-classification without throttling, add a second NVMe for the ZFS pool: the WD Black SN850X 2TB is a good pick for fast random I/O on the media directory.

Caveats and Gotchas

OCR language packs add size. Each additional Tesseract language adds ~30–100 MB to the container image. Install only what you need.

PDF/A conversion. Paperless-ngx converts documents to PDF/A for long-term archival by default. This is correct behavior, but it can change file sizes significantly β€” a 2 MB scanned invoice might become 4 MB PDF/A. Plan storage accordingly.

Search re-indexing takes time. After version upgrades, Paperless often needs to rebuild the full-text search index. On a large archive (5,000+ docs), this can take 20–30 minutes. Don't restart the container mid-reindex.

LXC networking quirk. If the webserver container can't resolve broker or db by hostname, your Docker network inside the unprivileged LXC may have a DNS issue. Adding --dns 1.1.1.1 to the Docker compose network config usually fixes it.

Backlog ingestion tip. If you're ingesting a backlog of 1,000+ documents, drop them in 100 at a time. Dumping a thousand PDFs at once creates a task queue backlog that can cause Redis to consume unexpected memory.

Verdict

Paperless-ngx on Proxmox LXC is one of the most immediately useful self-hosted services you can run. Setup time is under an hour, and once the auto-classifier trains on your document corpus, it genuinely handles most of the sorting work. The combination of full-text OCR search, auto-tagging, and correspondent tracking turns a folder of scanned chaos into an archive you can actually query.

The only rough edge in 2026: the mobile scanning workflow is still slightly more friction than a Google Drive scan-to-folder flow. The mobile apps have improved, but it's not quite frictionless yet. That said, everything else about this stack β€” including the lack of any per-document fee or cloud dependency β€” more than makes up for it.

If you're already running Proxmox and want one more LXC workload that pays back daily, this is it.

Disclosure: This post contains affiliate links. If you purchase through these links, I may earn a small commission at no extra cost to you.

Want this kind of setup for your business?

I deploy private, self-hosted infrastructure on Proxmox: AI, automation and internal tools on hardware you own, documented and handed off. See the Private AI Stack β†’

Not sure what you need? Book a free discovery call.

πŸ“¬Weekly Newsletter

Get the best home lab & AI content

No spam. One email per week. Unsubscribe anytime.

Share this article