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
10 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. I've been running it on Proxmox LXC for over a year, and it's one of those services I'd rebuild immediately if my home lab 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. I run nightly exports and sync 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 what I run 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.

    📬Weekly Newsletter

    Get the best home lab & AI content

    No spam. One email per week. Unsubscribe anytime.

    Share this article