
Self-host Paperless-ngx for document management. OCR setup, scanner integration, and automation tips for your home server.
Are you drowning in paper documents? Bills, receipts, tax forms, and important correspondence piling up in filing cabinets? There's a better way. Paperless-ngx is the ultimate self-hosted document management system that transforms your chaotic paper archive into a searchable, organized digital library—all running on your low-power home server.
In this comprehensive guide, we'll walk you through setting up Paperless-ngx with Docker Compose, configuring OCR for automatic text recognition, integrating your scanner, and optimizing everything for a low-power home server setup.


Paperless-ngx is the actively maintained fork of the original Paperless project, featuring a modern web interface and powerful automation capabilities. Here's why it's the go-to choice for self-hosters in 2025:


| Feature | Paperless-ngx | Google Drive | Evernote |
|---|---|---|---|
| Monthly Cost | $0 (self-hosted) | $2.99-$9.99/mo | $10.99/mo |
| Data Privacy | 100% local | Google servers | Evernote servers |
| OCR Quality | Excellent (Tesseract) | Good | Good |
| Custom Tags | Unlimited | Limited | Limited |
| API Access | Full REST API | Limited | Limited |
| Storage Limit | Your hardware | 15-200GB | 10-20GB |
Paperless-ngx is remarkably efficient. Here's what you need:
On an Intel N100 mini PC, expect:
Let's set up Paperless-ngx with all the bells and whistles. This configuration includes PostgreSQL for the database, Redis for task queuing, and Gotenberg/Tika for enhanced document processing.
/opt/paperless)Create a docker-compose.yml file:
version: "3.8"
services:
broker:
image: redis:7
container_name: paperless-redis
restart: unless-stopped
volumes:
- redis_data:/data
networks:
- paperless
db:
image: postgres:15
container_name: paperless-db
restart: unless-stopped
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: paperless
POSTGRES_USER: paperless
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-changeme}
networks:
- paperless
gotenberg:
image: gotenberg/gotenberg:7
container_name: paperless-gotenberg
restart: unless-stopped
command:
- "gotenberg"
- "--chromium-disable-javascript=true"
- "--chromium-allow-list=file:///tmp/.*"
networks:
- paperless
tika:
image: ghcr.io/paperless-ngx/tika:latest
container_name: paperless-tika
restart: unless-stopped
networks:
- paperless
webserver:
image: ghcr.io/paperless-ngx/paperless-ngx:latest
container_name: paperless
restart: unless-stopped
depends_on:
- db
- broker
- gotenberg
- tika
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_DBNAME: paperless
PAPERLESS_DBUSER: paperless
PAPERLESS_DBPASS: ${POSTGRES_PASSWORD:-changeme}
PAPERLESS_TIKA_ENABLED: 1
PAPERLESS_TIKA_ENDPOINT: http://tika:9998
PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000
PAPERLESS_URL: ${PAPERLESS_URL:-http://localhost:8000}
PAPERLESS_SECRET_KEY: ${PAPERLESS_SECRET_KEY:-change-me-to-a-long-random-string}
PAPERLESS_TIME_ZONE: ${TZ:-America/New_York}
PAPERLESS_OCR_LANGUAGE: eng
PAPERLESS_ADMIN_USER: ${ADMIN_USER:-admin}
PAPERLESS_ADMIN_PASSWORD: ${ADMIN_PASSWORD:-admin}
networks:
- paperless
volumes:
data:
media:
postgres_data:
redis_data:
networks:
paperless:
driver: bridge
Create a .env file in the same directory:
# Database
POSTGRES_PASSWORD=your-secure-password-here
# Paperless Settings
PAPERLESS_SECRET_KEY=generate-a-64-char-random-string
PAPERLESS_URL=https://paperless.yourdomain.com
TZ=America/New_York
# Admin Account
ADMIN_USER=admin
ADMIN_PASSWORD=your-admin-password
# OCR Language (comma-separated for multiple)
# PAPERLESS_OCR_LANGUAGE=eng+deu+fra
# Create directories
mkdir -p consume export
# Start all services
docker compose up -d
# Check logs
docker compose logs -f webserver
Wait 2-3 minutes for initial setup, then access Paperless at http://your-server-ip:8000.
OCR (Optical Character Recognition) is what makes Paperless-ngx truly powerful. Let's optimize it for your needs.
Add languages to your docker-compose.yml:
environment:
# Single language
PAPERLESS_OCR_LANGUAGE: eng
# Multiple languages (use + separator)
# PAPERLESS_OCR_LANGUAGE: eng+deu+fra+chi_sim
Available language codes include:
eng - Englishdeu - Germanfra - Frenchspa - Spanishchi_sim - Simplified Chinesechi_tra - Traditional Chinesejpn - Japanesekor - KoreanPaperless-ngx offers different OCR modes:
environment:
# Skip OCR if document already has text
PAPERLESS_OCR_MODE: skip
# OCR everything, even if text exists
# PAPERLESS_OCR_MODE: redo
# Force OCR, discard existing text
# PAPERLESS_OCR_MODE: force
# Skip OCR entirely (not recommended)
# PAPERLESS_OCR_MODE: skip_noarchive
Recommendation: Use skip mode for mixed archives (scanned + digital PDFs). It saves processing time on documents that already contain searchable text.
Fine-tune OCR quality vs. speed:
environment:
# Higher values = better quality, slower processing
PAPERLESS_OCR_DESKEW: true
PAPERLESS_OCR_ROTATE_PAGES: true
PAPERLESS_OCR_ROTATE_PAGES_THRESHOLD: 12
PAPERLESS_OCR_OUTPUT_TYPE: pdfa
PAPERLESS_OCR_CLEAN: clean
The magic of Paperless-ngx happens when you connect a document scanner. Here are the best approaches:
Budget Option (~$300):
Mid-Range (~$450):
Premium (~$600):
Most scanners can save directly to a network folder. Set up the consume folder:
# Create SMB share for scanner access
# Add to /etc/samba/smb.conf:
[paperless]
path = /opt/paperless/consume
browseable = yes
read only = no
guest ok = yes
create mask = 0644
directory mask = 0755
Configure your scanner to:
\\your-server-ip\paperlessDon't have a dedicated scanner? Use your phone:
Running Paperless-ngx on an Intel N100 or similar low-power hardware? Here's how to optimize:
Reduce memory footprint with these settings:
environment:
# Reduce web workers for low-RAM systems
PAPERLESS_WEBSERVER_WORKERS: 1
# Disable NLTK (natural language processing) if not needed
PAPERLESS_ENABLE_NLTK: false
# Limit concurrent OCR tasks
PAPERLESS_TASK_WORKERS: 1
# Reduce thumbnail generation workers
PAPERLESS_THREADS_PER_WORKER: 1
For PostgreSQL on low-power systems:
db:
image: postgres:15
command:
- "postgres"
- "-c"
- "shared_buffers=128MB"
- "-c"
- "effective_cache_size=256MB"
- "-c"
- "work_mem=4MB"
Example mount structure:
volumes:
- /mnt/ssd/paperless/data:/usr/src/paperless/data
- /mnt/hdd/paperless/media:/usr/src/paperless/media

Paperless-ngx can automatically organize documents using matching algorithms.
Create Tags in Settings → Tags:
bills, receipts, taxes, medical, contractsConfigure Matching for each tag:
Auto (uses machine learning)Regular Expression for precise controlCreate Correspondents for frequent senders:
amazon|amzn → Correspondent "Amazon"Set up document types for better organization:
InvoiceReceiptContractLetterManualCertificateTag: bills
Match: (electric|water|gas|utility|billing)
Algorithm: Regular Expression
Correspondent: Insurance Company
Match: (geico|state farm|allstate|progressive)
Algorithm: Regular Expression (case insensitive)
Your digital archive needs protection. Here's a solid backup approach:
Add a backup service to your stack:
services:
backup:
image: offen/docker-volume-backup:latest
container_name: paperless-backup
restart: unless-stopped
environment:
BACKUP_CRON_EXPRESSION: "0 3 * * *"
BACKUP_FILENAME: "paperless-backup-%Y%m%d.tar.gz"
BACKUP_RETENTION_DAYS: 30
volumes:
- data:/backup/data:ro
- media:/backup/media:ro
- postgres_data:/backup/postgres:ro
- /opt/backups/paperless:/archive
# Stop services
docker compose down
# Restore volumes from backup
tar -xzf paperless-backup-YYYYMMDD.tar.gz -C /
# Restart services
docker compose up -d
# Rebuild search index if needed
docker compose exec webserver document_index reindex
Symptoms: Documents imported but text not searchable
Solutions:
docker compose psPAPERLESS_OCR_LANGUAGEdocker compose logs webserver | grep -i ocrSymptoms: Web UI laggy, documents take forever to process
Solutions:
PAPERLESS_TASK_WORKERS to 1docker statsSymptoms: Scanner can't reach consume folder
Solutions:
smbclient //server-ip/paperless -U guest -NSymptoms: Files sit in consume folder indefinitely
Solutions:
ls -la consume/docker compose exec webserver ls -la /usr/src/paperless/consumePaperless-ngx transforms document management from a chore into a seamless, automated system. With intelligent OCR, automatic tagging, and powerful search, you'll never lose a document again. Running on a low-power home server, the entire system costs less than $2/month in electricity while providing enterprise-grade document management.
Key Takeaways:
Ready to go paperless? Start with the Docker Compose setup above, connect your scanner, and watch as your paper chaos transforms into an organized, searchable archive.

Use Cases
Deploy Immich on your low-power home server. Complete Docker Compose setup, mobile backup config, and hardware transcoding for Intel N100.

Use Cases
Build a private AI automation pipeline with n8n and Ollama. Self-hosted workflows for RSS summarization, email processing, and smart home automation.

Use Cases
Run your own AI assistant on low-power hardware. Complete guide to Ollama and Open WebUI setup with Docker on Intel N100.
Check out our build guides to get started with hardware.
View Build Guides