Paperless-ngx Complete Setup Guide 2026: Go Paperless with Self-Hosted Document Management
Published on January 10, 2026
Introduction
Paperless-ngx is a powerful, open-source document management system that transforms your physical documents into a searchable online archive. It uses Optical Character Recognition (OCR) to extract text from scanned documents, making them fully searchable, taggable, and organized. Itโs a community-maintained fork of the original Paperless project with enhanced features like machine learning for better document classification.
This comprehensive guide covers every aspect of Paperless-ngx deployment, from basic Docker installation to advanced configurations including bare metal installation, reverse proxy setup, scanner integration, and enterprise-grade backup strategies. Weโll explain every command, what it does, why itโs run, and potential outputs or errors.
Key Terminology
Before we begin, letโs define some important terms:
| Term | Definition |
|---|---|
| Docker | A platform for developing, shipping, and running applications in containersโlightweight, isolated environments that bundle an application with all its dependencies |
| Docker Compose | A tool for defining and running multi-container Docker applications using a YAML configuration file |
| Bare Metal | Installing software directly on the host operating system without using containers or virtualization |
| OCR | Optical Character Recognitionโtechnology that converts images of text into machine-readable text |
| Container | A lightweight, standalone, executable package that includes everything needed to run software |
| Redis | An in-memory data structure store used by Paperless-ngx for task queuing and caching |
| PostgreSQL | A powerful, open-source relational database system (recommended for Paperless-ngx) |
Estimated Time
| Installation Method | Estimated Time |
|---|---|
| Docker (Interactive Script) | 15-30 minutes |
| Docker (Manual Setup) | 30-60 minutes |
| Bare Metal (Linux) | 1-2 hours |
| NAS Installation | 30-60 minutes |
Important Notes Before Starting
๐ Security: Use strong passwords and avoid exposing ports directly to the internet without a reverse proxy (like Nginx or Caddy) with HTTPS.
- Backup First: Always back up your system before proceeding, as installations can modify files or require administrative privileges
- Internet Required: Youโll need internet access for downloading packages and Docker images
- Terminal Access: All commands are run in a terminal (Command Prompt/PowerShell on Windows, Terminal on Linux/macOS)
- Administrative Access: Youโll need admin rights (
sudoon Linux/macOS, Administrator on Windows) - Version Note: This guide is based on Paperless-ngx version 2.x (January 2026). Always check the official documentation for updates
Who Is This Guide For?
- Beginners wanting to go paperless and digitize their documents
- Intermediate users looking to optimize their existing Paperless-ngx installation
- Advanced users seeking bare metal deployment, custom configurations, or NAS integration
- NAS users (Synology, Unraid, TrueNAS) wanting to leverage existing hardware
What Makes Paperless-ngx Special?
| Feature | Description |
|---|---|
| Full-Text OCR Search | Search document contents using Tesseract OCR |
| Automatic Tagging | Machine learning-based automatic document classification |
| Consume Folder | Drop documents into a folder for automatic processing |
| Email Integration | Automatically import documents from email attachments |
| Multi-User Support | Role-based access control for teams and families |
| Mobile Friendly | Responsive web interface works on any device |
| Document Matching | Automatically assign correspondents and document types |
| Office Document Support | Process Word, Excel, and other office formats with Tika |
โ ๏ธ Important: Paperless-ngx stores documents without encryption by default. Always run it on a trusted local server and maintain proper backups.
Part 1: Understanding Paperless-ngx Architecture
Before diving into installation, understanding Paperless-ngxโs architecture helps with troubleshooting and optimization.
Core Components
Paperless-ngx consists of several services working together:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ PAPERLESS-NGX STACK โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Web Server โ โ Document โ โ
โ โ (Gunicorn/ โโโโโโโโบโ Consumer โ โ
โ โ Django) โ โ (Background) โ โ
โ โ Port 8000 โ โ โ โ
โ โโโโโโโโโโโฌโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโ โ
โ โ PostgreSQL โ โ Redis โ โ
โ โ (or SQLite/ โ โ (Task Queue/ โ โ
โ โ MariaDB) โ โ Scheduler) โ โ
โ โโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Tika โ โ Gotenberg โ โ
โ โ (Office Docs) โ โ (PDF Conversion) โ โ
โ โ [Optional] โ โ [Optional] โ โ
โ โโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | Component | Purpose | Notes |
|---|---|---|
webserver | Web interface, API, background tasks | Main entry point for users |
consumer | Watches consume folder, processes documents | Runs within webserver container |
PostgreSQL | Stores metadata, user data, document info | Recommended for production |
Redis | Task queue, scheduled jobs, caching | Required for task scheduling |
Tika | Extracts text from Office documents | Optional, increases RAM usage |
Gotenberg | Converts documents to PDF | Optional, for advanced conversions |
Critical Data Locations
Understanding where Paperless-ngx stores data is essential for backups:
| Location | Contains | Backup Priority |
|---|---|---|
data/ | SQLite database (if used), index | CRITICAL |
media/documents/ | Original and archived documents | CRITICAL |
media/thumbnails/ | Document thumbnails | Can regenerate |
consume/ | Documents waiting to be processed | Temporary |
export/ | Exported document backups | Important |
Part 2: System Requirements
General Prerequisites (Before Any Installation)
Before installing Paperless-ngx, complete these preparation steps:
1. Update Your System
Updating ensures all packages are current to avoid compatibility issues.
Linux (Debian/Ubuntu):
# Update package lists and upgrade all packages
sudo apt update && sudo apt upgrade -y
# Explanation:
# - sudo: Run with administrator privileges (prompts for password)
# - apt: Debian/Ubuntu package manager
# - update: Refreshes the list of available packages
# - upgrade: Installs newer versions of installed packages
# - -y: Automatically answer "yes" to prompts Linux (Fedora/RHEL/CentOS):
sudo dnf update -y macOS:
# Using Apple's built-in software updater
softwareupdate -i -a
# Explanation:
# - -i: Install updates
# - -a: All available updates Windows:
- Open Settings โ Update & Security โ Windows Update
- Click Check for updates
- Install all available updates
- Restart if prompted
2. Verify Administrative Access
You need admin privileges to install software:
| Platform | How to Verify |
|---|---|
| Linux/macOS | Run sudo whoami - should output โrootโ |
| Windows | Right-click Command Prompt โ โRun as administratorโ |
3. Check Available Storage
# Linux/macOS
df -h
# Windows (PowerShell)
Get-PSDrive -PSProvider FileSystem Ensure you have at least:
- 10 GB free for installation and dependencies
- Additional space for your documents (varies by archive size)
4. Configure Firewall (if enabled)
Paperless-ngx uses port 8000 by default. Allow this port if you have a firewall:
Linux (UFW):
sudo ufw allow 8000/tcp
sudo ufw status Linux (firewalld):
sudo firewall-cmd --permanent --add-port=8000/tcp
sudo firewall-cmd --reload Windows:
- Open Windows Defender Firewall
- Click Advanced settings โ Inbound Rules โ New Rule
- Select Port โ TCP โ 8000 โ Allow
macOS: macOS firewall typically doesnโt block outbound connections. If using a third-party firewall, allow port 8000.
5. Optional Preparations
- Scanner or Camera: For digitizing physical documents (phone scanning apps work well)
- Domain Name: If you plan to access remotely with HTTPS
- Backup Solution: Plan for backing up your document archive
Hardware Requirements
| Component | Minimum | Recommended | Large Archives (100K+ docs) |
|---|---|---|---|
| RAM | 2 GB | 4-8 GB | 16+ GB |
| CPU | 2 cores | 4 cores | 8+ cores |
| OS Storage | 20 GB SSD | 50 GB SSD | 100 GB+ NVMe |
| Document Storage | Variable | SSD recommended | SSD for DB, HDD for docs |
๐ก Tip: OCR processing is CPU-intensive. More cores = faster document processing.
Storage Considerations
/โโ Fast Storage (SSD/NVMe)
โ โโโ /paperless/data (Database, Index)
โ โโโ /paperless/media/thumbnails
โ
โโโ Bulk Storage (HDD/NAS acceptable)
โโโ /paperless/media/documents (Original files) Operating System Compatibility
| OS | Support Level | Notes |
|---|---|---|
| Linux (Ubuntu/Debian) | โ Best | Recommended for production |
| Linux (Other distros) | โ Good | Docker works on most distros |
| Windows (WSL2 + Docker) | โ ๏ธ Functional | Requires Docker Desktop |
| macOS | โ ๏ธ Functional | Docker Desktop required |
| Synology DSM 7.2+ | โ Good | Container Manager supported |
| Unraid | โ Good | Community templates available |
| TrueNAS Scale | โ Good | Docker Compose via Portainer |
Software Prerequisites
| Component | Required Version | Purpose |
|---|---|---|
| Docker | 20.10+ | Container runtime |
| Docker Compose | v2.0+ | Multi-container orchestration |
| Python | 3.10-3.12 | For bare metal installations |
| Redis | 6.0+ | Task queue (bare metal) |
| PostgreSQL | 13+ | Recommended database |
Part 3: Docker Installation Methods
Docker is the recommended installation method for Paperless-ngx. It simplifies setup, updates, and dependency management.
Method 1: Interactive Installation Script (Easiest)
This is the quickest way to get Paperless-ngx running.
Prerequisites
Ensure Docker and Docker Compose are installed on your system.
For Linux:
# Step 1: Download and run the installation script
bash -c "$(curl --location --silent --show-error https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/install-paperless-ngx.sh)" Command Explanation:
curl: Command-line tool for downloading files from URLs--location: Follows HTTP redirects (if the URL moves, it will follow)--silent: Hides progress bar and other output--show-error: Shows error messages if something goes wrongbash -c: Executes the downloaded script in a Bash shell
What this script does:
- Checks for Docker and Docker Compose installation
- Asks configuration questions (database type, OCR language, port, etc.)
- Creates a directory with
docker-compose.ymland.envfiles - Pulls Docker images from the registry
- Creates your superuser account
- Starts all containers in the background
Expected Prompts:
Enter the installation directory [./paperless-ngx]:
Enter the port for the web interface [8000]:
Select database backend (postgres/sqlite) [postgres]:
Enter OCR language(s) [eng]:
Enter admin username [admin]:
Enter admin password: ๐ก Tip: Press Enter to accept default values shown in brackets.
For macOS:
macOS requires additional tools before running the script:
# Step 1: Install Homebrew (if not already installed)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Step 2: Install GNU sed and wget (required by the script)
brew install gnu-sed wget
# Step 3: Add GNU sed to your PATH
# For bash users, add to ~/.bash_profile:
echo 'export PATH="/opt/homebrew/opt/gnu-sed/libexec/gnubin:$PATH"' >> ~/.bash_profile
source ~/.bash_profile
# For zsh users, add to ~/.zshrc:
echo 'export PATH="/opt/homebrew/opt/gnu-sed/libexec/gnubin:$PATH"' >> ~/.zshrc
source ~/.zshrc
# Step 4: Run the installation script
bash -c "$(curl --location --silent --show-error https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/install-paperless-ngx.sh)" Why these steps are needed:
- macOS uses BSD sed, which has different syntax than GNU sed
- The installation script requires GNU sed to function properly
- wget is needed for downloading files
Method 2: Manual Docker Compose Setup
This method gives you more control over the configuration.
Step 1: Install Docker
Linux (Ubuntu/Debian):
# Remove old Docker versions
for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do
sudo apt-get remove -y $pkg 2>/dev/null
done
# Install prerequisites
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
# Add Docker's official GPG key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg |
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Add Docker repository
echo
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" |
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker Engine
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
docker-buildx-plugin docker-compose-plugin
# Add your user to the docker group (optional, avoids using sudo)
sudo usermod -aG docker $USER
newgrp docker
# Verify installation
docker --version
docker compose version Windows (Docker Desktop + WSL2):
- Enable Virtualization in your BIOS/UEFI settings
- Install WSL2:
# Open PowerShell as Administrator wsl --install # Restart your computer when prompted - Download Docker Desktop from docker.com
- During installation, ensure โUse WSL 2 instead of Hyper-Vโ is checked
- Configure Docker Desktop:
- Open Docker Desktop โ Settings โ Resources โ WSL Integration
- Enable integration with your default WSL distro
- Click โApply & Restartโ
- Verify installation in PowerShell:
docker --version docker compose version
macOS (Docker Desktop):
- Download Docker Desktop from docker.com
- For Apple Silicon (M1/M2/M3/M4): Download โApple Chipโ version
- For Intel Macs: Download โIntel Chipโ version
- Drag Docker.app to Applications folder
- Launch Docker from Applications
- Configure Resources:
- Docker Desktop โ Settings โ Resources
- Allocate at least 4GB RAM (8GB recommended)
- Verify installation in Terminal:
docker --version docker compose version
Step 2: Create Project Directory
# Linux/macOS
mkdir -p ~/paperless-ngx
cd ~/paperless-ngx # Windows PowerShell
mkdir C:Users$env:USERNAMEDocumentsDockerpaperless-ngx
cd C:Users$env:USERNAMEDocumentsDockerpaperless-ngx Step 3: Download Docker Compose Files
Navigate to Paperless-ngx GitHub Docker Compose Directory and download the appropriate files.
Choose your docker-compose file based on your needs:
| File | Database | Office Support | Use Case |
|---|---|---|---|
docker-compose.sqlite.yml | SQLite | โ | Small personal use |
docker-compose.postgres.yml | PostgreSQL | โ | Recommended for most users |
docker-compose.mariadb.yml | MariaDB | โ | Alternative to PostgreSQL |
docker-compose.sqlite-tika.yml | SQLite | โ | Personal + Office docs |
docker-compose.postgres-tika.yml | PostgreSQL | โ | Recommended full setup |
docker-compose.mariadb-tika.yml | MariaDB | โ | Alternative + Office docs |
Linux/macOS Download:
# Download the compose file (PostgreSQL + Tika recommended)
wget https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/docker/compose/docker-compose.postgres-tika.yml
# Rename to docker-compose.yml
mv docker-compose.postgres-tika.yml docker-compose.yml
# Download environment files
wget https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/docker/compose/docker-compose.env
wget https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/docker/compose/.env Windows PowerShell Download:
# Download the compose file
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/docker/compose/docker-compose.postgres-tika.yml" -OutFile "docker-compose.yml"
# Download environment files
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/docker/compose/docker-compose.env" -OutFile "docker-compose.env"
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/docker/compose/.env" -OutFile ".env" Step 4: Create Data Directories
Linux/macOS:
# Create directories for persistent data
mkdir -p ./consume ./data ./media ./export ./db Windows:
# Create directories
New-Item -ItemType Directory -Path consume, data, media, export, db -Force Step 5: Configure Environment Variables
Edit the docker-compose.env file with your preferred text editor:
# Linux/macOS
nano docker-compose.env
# Or use any text editor Essential Configuration Options:
# ==================================================
# PAPERLESS-NGX ENVIRONMENT CONFIGURATION
# ==================================================
# --------------------------------------------------
# REQUIRED: Secret Key for Security
# --------------------------------------------------
# Generate a random string (at least 50 characters)
# CRITICAL: Change this from the default!
# You can generate one using:
# Linux/macOS: openssl rand -hex 32
# Python: python -c "import secrets; print(secrets.token_hex(32))"
PAPERLESS_SECRET_KEY=your-super-secret-random-string-change-this-immediately
# --------------------------------------------------
# REQUIRED: Timezone Setting
# --------------------------------------------------
# Find yours at: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
PAPERLESS_TIME_ZONE=America/New_York
# --------------------------------------------------
# REQUIRED: OCR Language
# --------------------------------------------------
# Use ISO 639-2 language codes
# Multiple languages: eng+deu+fra
# Common codes: eng (English), deu (German), fra (French), spa (Spanish)
PAPERLESS_OCR_LANGUAGE=eng
# --------------------------------------------------
# OPTIONAL: Admin Account (Auto-created on first run)
# --------------------------------------------------
# If not set, you'll create the admin via command line
PAPERLESS_ADMIN_USER=admin
PAPERLESS_ADMIN_PASSWORD=your-secure-password
# --------------------------------------------------
# OPTIONAL: Web Server Port
# --------------------------------------------------
# Default is 8000. Change if port conflicts exist.
# PAPERLESS_PORT=8000
# --------------------------------------------------
# USER MAPPING (IMPORTANT for Linux)
# --------------------------------------------------
# Run 'id' command to get your user/group IDs
# Default is 1000 for first user on most systems
USERMAP_UID=1000
USERMAP_GID=1000
# --------------------------------------------------
# OPTIONAL: Consumer Settings
# --------------------------------------------------
# Polling interval in seconds (use for network shares)
# Set to 0 to use inotify (default, works on local storage)
# PAPERLESS_CONSUMER_POLLING=60
# Number of threads for OCR processing
# PAPERLESS_OCR_THREADS=4 Generating a Secret Key:
# Linux/macOS
openssl rand -hex 32
# Python (any platform)
python -c "import secrets; print(secrets.token_hex(32))" Step 6: Modify docker-compose.yml for Volume Paths
Volumes mount host directories to container directories, ensuring data persists across container restarts.
Understanding Volume Syntax:
/host/path:/container/path - Left side: Path on your host machine (where data is actually stored)
- Right side: Path inside the container (where the application expects data)
If you want to use absolute paths instead of relative paths, edit docker-compose.yml:
# Example volume mapping changes
services:
webserver:
volumes:
# Change from relative to absolute paths
# Original: - ./data:/usr/src/paperless/data
- /home/username/paperless-ngx/data:/usr/src/paperless/data
- /home/username/paperless-ngx/media:/usr/src/paperless/media
- /home/username/paperless-ngx/export:/usr/src/paperless/export
- /home/username/paperless-ngx/consume:/usr/src/paperless/consume Windows Path Example:
volumes:
- C:UsersYourUserDocumentsDockerpaperless-ngxdata:/usr/src/paperless/data
- C:UsersYourUserDocumentsDockerpaperless-ngxmedia:/usr/src/paperless/media
- C:UsersYourUserDocumentsDockerpaperless-ngxexport:/usr/src/paperless/export
- C:UsersYourUserDocumentsDockerpaperless-ngxconsume:/usr/src/paperless/consume Changing the Web Interface Port:
If port 8000 is already in use, modify the ports section:
services:
webserver:
ports:
- "8010:8000" # Left is host port, right is container port Rootless Container Setup (Optional):
For running containers without root privileges, add user mapping:
services:
webserver:
image: ghcr.io/paperless-ngx/paperless-ngx:latest
user: "1000:1000" # Replace with your UID:GID To find your UID and GID:
# Get your user and group IDs
id -u # User ID (UID)
id -g # Group ID (GID) Step 7: Pull Docker Images
docker compose pull What this does: Downloads all required Docker images (Paperless-ngx, PostgreSQL, Redis, Tika, Gotenberg) from the container registry.
Step 8: Create Superuser Account
docker compose run --rm webserver createsuperuser What this does: Creates an administrator account for the web interface. Youโll be prompted for:
- Username
- Email address
- Password (entered twice)
๐ก Tip: Store these credentials securely. Youโll need them to log in.
Step 9: Start Paperless-ngx
# Start in detached mode (background)
docker compose up -d What this does:
-d: Runs containers in the background (detached mode)- Creates and starts all containers defined in docker-compose.yml
- First startup may take 2-5 minutes
Step 10: Verify Installation
# Check container status
docker compose ps Expected output:
NAME STATUS PORTS
paperless-ngx-broker-1 Up (healthy)
paperless-ngx-db-1 Up (healthy)
paperless-ngx-webserver-1 Up (healthy) 0.0.0.0:8000->8000/tcp
paperless-ngx-gotenberg-1 Up (healthy)
paperless-ngx-tika-1 Up (healthy) Step 11: Access Web Interface
- Open your web browser
- Navigate to:
http://localhost:8000orhttp://YOUR_SERVER_IP:8000 - Log in with the superuser credentials you created
๐ Congratulations! Paperless-ngx is now running!
Method 3: Building Docker Image from Source (Advanced)
For custom modifications or development purposes, you can build the Docker image from source code.
Step 1: Clone the Repository
git clone https://github.com/paperless-ngx/paperless-ngx.git
cd paperless-ngx What this does:
git clone: Downloads the entire source code repositorycd: Changes into the downloaded directory
Step 2: Download Configuration Files
Same as Method 2 - download docker-compose.yml and .env files, but place them in the repository root.
Step 3: Modify docker-compose.yml for Building
Change the image reference to build from local source:
services:
webserver:
# Comment out or remove the image line:
# image: ghcr.io/paperless-ngx/paperless-ngx:latest
# Add build instruction instead:
build: . Step 4: Build and Start
# Build the Docker image from source (takes 10-30 minutes)
docker compose build
# Start the containers
docker compose up -d What this does:
docker compose build: Compiles the code and creates a custom Docker image- This is slower but allows customization of the application
Post-Docker Installation Steps (All Methods)
After successfully installing Paperless-ngx with Docker:
1. First-Time Configuration
- Access the web UI at
http://localhost:8000 - Log in with your superuser credentials
- Navigate to Settings to configure:
- Document types (Invoice, Receipt, Contract, etc.)
- Correspondents (people/companies you communicate with)
- Tags for organization
- Storage paths (if using custom paths)
2. Adding Documents
Via Consume Folder:
- Place PDF, image, or office documents in the
consumefolder - Paperless automatically processes them (OCR, indexing)
Via Web Interface:
- Click Upload in the web UI
- Drag and drop files
Via Email (if configured):
- Forward or send emails with attachments to your configured email address
3. Managing Containers
# View running containers
docker compose ps
# View logs (real-time)
docker compose logs -f
# Press Ctrl+C to exit
# Stop all containers
docker compose down
# Restart containers (after config changes)
docker compose down && docker compose up -d
# Restart a specific service
docker compose restart webserver 4. Updating Paperless-ngx
# Pull latest images
docker compose pull
# Recreate containers with new images
docker compose up -d
# Optional: Remove old unused images
docker image prune -a 5. Troubleshooting Docker Installation
View logs for errors:
docker compose logs -f webserver Permission issues (Linux):
# Fix ownership of data directories
sudo chown -R $USER:$USER ./data ./media ./consume ./export macOS/Windows slow performance:
- Docker Desktop has volume mount overhead
- Consider using Mutagen for faster file sync
NFS/Network shares not detecting files:
# Add to docker-compose.env
PAPERLESS_CONSUMER_POLLING=60 Database connection errors:
# Check if database container is running
docker compose ps db
# View database logs
docker compose logs db Part 4: NAS-Specific Installation
Synology NAS (Container Manager)
Prerequisites
- Synology DSM 7.2 or later
- Container Manager package installed (from Package Center)
- At least 4GB RAM (8GB recommended)
- SSH access enabled (for UID/GID lookup)
Step 1: Enable SSH (Temporary)
- Open Control Panel โ Terminal & SNMP
- Check Enable SSH service
- Click Apply
Step 2: Get User ID and Group ID
Connect via SSH and run:
id your_username Note the uid and gid values (commonly 1000 or 1026 on Synology).
Step 3: Create Folder Structure
Using File Station, create:
/docker/paperless-ngx/
โโโ consume/
โโโ data/
โโโ db/
โโโ export/
โโโ media/
โโโ redis/ Step 4: Prepare Configuration Files
Create docker-compose.yml in /docker/paperless-ngx/:
version: "3.8"
services:
broker:
image: docker.io/library/redis:7
container_name: paperless-redis
restart: unless-stopped
volumes:
- /volume1/docker/paperless-ngx/redis:/data
db:
image: docker.io/library/postgres:16
container_name: paperless-db
restart: unless-stopped
volumes:
- /volume1/docker/paperless-ngx/db:/var/lib/postgresql/data
environment:
POSTGRES_DB: paperless
POSTGRES_USER: paperless
POSTGRES_PASSWORD: paperless
webserver:
image: ghcr.io/paperless-ngx/paperless-ngx:latest
container_name: paperless-ngx
restart: unless-stopped
depends_on:
- db
- broker
ports:
- "8010:8000"
volumes:
- /volume1/docker/paperless-ngx/data:/usr/src/paperless/data
- /volume1/docker/paperless-ngx/media:/usr/src/paperless/media
- /volume1/docker/paperless-ngx/export:/usr/src/paperless/export
- /volume1/docker/paperless-ngx/consume:/usr/src/paperless/consume
environment:
PAPERLESS_REDIS: redis://broker:6379
PAPERLESS_DBHOST: db
PAPERLESS_DBNAME: paperless
PAPERLESS_DBUSER: paperless
PAPERLESS_DBPASS: paperless
PAPERLESS_SECRET_KEY: change-me-to-a-long-random-string
PAPERLESS_TIME_ZONE: America/New_York
PAPERLESS_OCR_LANGUAGE: eng
PAPERLESS_ADMIN_USER: admin
PAPERLESS_ADMIN_PASSWORD: admin
USERMAP_UID: 1026
USERMAP_GID: 100 โ ๏ธ Important: Change
PAPERLESS_SECRET_KEY,PAPERLESS_ADMIN_PASSWORD, andUSERMAP_UID/USERMAP_GIDto your actual values.
Step 5: Deploy via Container Manager
- Open Container Manager โ Project
- Click Create
- Set Project name:
paperless-ngx - Set Path:
/docker/paperless-ngx - Container Manager will detect
docker-compose.yml - Click Next โ Done to build and start
Step 6: Access Paperless-ngx
Navigate to http://YOUR_SYNOLOGY_IP:8010
TrueNAS Scale
Prerequisites
- TrueNAS Scale 24.04 or later
- Portainer installed (recommended for Docker Compose management)
- Sufficient RAM (4GB minimum, 8GB recommended)
Step 1: Create Datasets
In the TrueNAS web UI:
- Go to Storage โ Datasets
- Create datasets for:
paperless-ngx/datapaperless-ngx/mediapaperless-ngx/consumepaperless-ngx/exportpaperless-ngx/dbpaperless-ngx/redis
Step 2: Install Portainer (if not installed)
- Go to Apps โ Discover Apps
- Search for โPortainerโ
- Click Install
Step 3: Deploy via Portainer
- Access Portainer (usually at
http://YOUR_TRUENAS_IP:9443) - Go to Stacks โ Add Stack
- Name:
paperless-ngx - Paste the docker-compose.yml content (similar to Synology example)
- Adjust volume paths to match your TrueNAS dataset paths:
volumes: - /mnt/pool/paperless-ngx/data:/usr/src/paperless/data # ... etc - Click Deploy the stack
Unraid
Option 1: Community Applications
- Go to Apps tab
- Search for โPaperless-ngxโ
- Click Install
- Configure paths and settings in the template
- Click Apply
Option 2: Docker Compose
- Install the Compose Manager plugin
- Create a new stack with the docker-compose.yml content
- Adjust paths to Unraid format:
volumes: - /mnt/user/appdata/paperless-ngx/data:/usr/src/paperless/data # ... etc
Part 5: Bare Metal Installation (Linux Only)
โ ๏ธ Note: Bare metal installation is more complex and not recommended for beginners. Docker is preferred for easier maintenance and updates.
Prerequisites
- A Debian/Ubuntu-based Linux distribution
- Python 3.10-3.12
- Root or sudo access
Step 1: Install System Dependencies
# Update package list
sudo apt update
# Install Python and development tools
sudo apt install -y python3 python3-pip python3-dev python3-setuptools python3-wheel build-essential
# Install image processing dependencies
sudo apt install -y imagemagick fonts-liberation
# Install PDF and document processing
sudo apt install -y ghostscript icc-profiles-free qpdf unpaper gnupg libmagic-dev poppler-utils
# Install OCR engine and language packs
sudo apt install -y tesseract-ocr tesseract-ocr-eng
# Add more languages as needed: tesseract-ocr-deu tesseract-ocr-fra etc.
# Install database libraries
sudo apt install -y libpq-dev # For PostgreSQL
# Install barcode detection
sudo apt install -y libzbar0
# Install additional libraries
sudo apt install -y liblept5 libxml2 pngquant zlib1g What each package does:
imagemagick: Converts images and PDFstesseract-ocr: Performs optical character recognitionghostscript: Processes PostScript and PDF filesqpdf: PDF transformation toolunpaper: Post-processing for scanned pages
Step 2: Install Redis
# Install Redis
sudo apt install -y redis-server
# Enable Redis to start on boot
sudo systemctl enable redis-server
# Start Redis
sudo systemctl start redis-server
# Verify Redis is running
redis-cli ping
# Should output: PONG Step 3: Install and Configure PostgreSQL
# Install PostgreSQL
sudo apt install -y postgresql postgresql-contrib
# Start PostgreSQL
sudo systemctl enable postgresql
sudo systemctl start postgresql
# Create database and user
sudo -u postgres psql <<EOF
CREATE USER paperless WITH PASSWORD 'your-secure-password';
CREATE DATABASE paperless OWNER paperless;
GRANT ALL PRIVILEGES ON DATABASE paperless TO paperless;
q
EOF Step 4: Create System User
# Create a system user for Paperless-ngx
sudo adduser paperless --system --home /opt/paperless --group Step 5: Download Paperless-ngx
# Switch to paperless user's home directory
cd /opt/paperless
# Download the latest release (check GitHub for current version)
sudo -u paperless curl -O -L https://github.com/paperless-ngx/paperless-ngx/releases/download/v2.14.0/paperless-ngx-v2.14.0.tar.xz
# Extract the archive
sudo -u paperless tar -xf paperless-ngx-v2.14.0.tar.xz
# Move contents
sudo -u paperless mv paperless-ngx/* .
sudo -u paperless rmdir paperless-ngx Step 6: Create Python Virtual Environment
# Create virtual environment
sudo -u paperless python3 -m venv /opt/paperless/venv
# Activate virtual environment and install dependencies
sudo -u paperless /opt/paperless/venv/bin/pip install --upgrade pip
sudo -u paperless /opt/paperless/venv/bin/pip install -r /opt/paperless/requirements.txt Step 7: Configure Paperless-ngx
Create /opt/paperless/paperless.conf:
sudo -u paperless nano /opt/paperless/paperless.conf Add the following configuration:
# Required settings
PAPERLESS_SECRET_KEY=your-random-secret-key-at-least-50-characters
PAPERLESS_TIME_ZONE=America/New_York
PAPERLESS_OCR_LANGUAGE=eng
# Database settings (PostgreSQL)
PAPERLESS_DBENGINE=postgresql
PAPERLESS_DBHOST=localhost
PAPERLESS_DBPORT=5432
PAPERLESS_DBNAME=paperless
PAPERLESS_DBUSER=paperless
PAPERLESS_DBPASS=your-secure-password
# Redis settings
PAPERLESS_REDIS=redis://localhost:6379
# Directory settings
PAPERLESS_DATA_DIR=/opt/paperless/data
PAPERLESS_MEDIA_ROOT=/opt/paperless/media
PAPERLESS_CONSUMPTION_DIR=/opt/paperless/consume
# Optional settings
PAPERLESS_OCR_THREADS=4 Step 8: Create Required Directories
sudo -u paperless mkdir -p /opt/paperless/{data,media,consume,export} Step 9: Initialize Database
cd /opt/paperless
sudo -u paperless /opt/paperless/venv/bin/python manage.py migrate Step 10: Create Superuser
sudo -u paperless /opt/paperless/venv/bin/python manage.py createsuperuser Step 11: Create Systemd Services
Create /etc/systemd/system/paperless-webserver.service:
[Unit]
Description=Paperless-ngx Web Server
After=network.target redis.service postgresql.service
[Service]
User=paperless
Group=paperless
WorkingDirectory=/opt/paperless
ExecStart=/opt/paperless/venv/bin/gunicorn -c /opt/paperless/gunicorn.conf.py paperless.asgi:application
Restart=on-failure
[Install]
WantedBy=multi-user.target Create /etc/systemd/system/paperless-consumer.service:
[Unit]
Description=Paperless-ngx Document Consumer
After=network.target redis.service postgresql.service
[Service]
User=paperless
Group=paperless
WorkingDirectory=/opt/paperless
ExecStart=/opt/paperless/venv/bin/python manage.py document_consumer
Restart=on-failure
[Install]
WantedBy=multi-user.target Create /etc/systemd/system/paperless-scheduler.service:
[Unit]
Description=Paperless-ngx Task Scheduler
After=network.target redis.service postgresql.service
[Service]
User=paperless
Group=paperless
WorkingDirectory=/opt/paperless
ExecStart=/opt/paperless/venv/bin/celery --app paperless beat --loglevel INFO
Restart=on-failure
[Install]
WantedBy=multi-user.target Create /etc/systemd/system/paperless-task-queue.service:
[Unit]
Description=Paperless-ngx Task Queue
After=network.target redis.service postgresql.service
[Service]
User=paperless
Group=paperless
WorkingDirectory=/opt/paperless
ExecStart=/opt/paperless/venv/bin/celery --app paperless worker --loglevel INFO
Restart=on-failure
[Install]
WantedBy=multi-user.target Step 12: Enable and Start Services
sudo systemctl daemon-reload
sudo systemctl enable paperless-webserver paperless-consumer paperless-scheduler paperless-task-queue
sudo systemctl start paperless-webserver paperless-consumer paperless-scheduler paperless-task-queue What each service does:
paperless-webserver: Serves the web UI and APIpaperless-consumer: Watches the consume folder and processes new documentspaperless-scheduler: Runs periodic maintenance taskspaperless-task-queue: Processes background jobs (OCR, thumbnails)
Step 13: Test with Development Server (Optional)
Before using systemd services, you can test with the built-in development server:
sudo -Hu paperless bash -c "cd /opt/paperless/src && python3 manage.py runserver --noreload" What this does:
- Starts a development server on
http://localhost:8000 --noreload: Prevents auto-reloading which can cause issues- Press
Ctrl+Cto stop when done testing
โ ๏ธ Warning: The development server is NOT suitable for production use!
Step 14: Optional Configurations
ImageMagick PDF Policy
By default, ImageMagick may block PDF processing for security. Enable it:
# Edit ImageMagick policy
sudo nano /etc/ImageMagick-6/policy.xml
# Or on some systems:
sudo nano /etc/ImageMagick-7/policy.xml Find and modify (or add) the PDF policy line:
<!-- Change from this: -->
<policy domain="coder" rights="none" pattern="PDF" />
<!-- To this: -->
<policy domain="coder" rights="read|write" pattern="PDF" /> This allows ImageMagick to read and write PDF files, which is necessary for document processing.
Samba Share for Consume Folder
To allow network access to the consume folder (e.g., for scanners):
# Install Samba
sudo apt install -y samba
# Create Samba user (use your system username)
sudo smbpasswd -a paperless Add the following to /etc/samba/smb.conf:
[paperless-consume]
path = /opt/paperless/consume
browseable = yes
read only = no
guest ok = no
valid users = paperless
comment = Paperless-ngx Consume Folder Then restart Samba:
sudo systemctl restart smbd Access from Windows: \\YOUR_SERVER_IP\paperless-consume
NLTK Data for Natural Language Processing
Paperless-ngx uses NLTK for text processing. Download required data:
sudo -Hu paperless python3 -m nltk.downloader -d /usr/share/nltk_data stopwords punkt What this does:
- Downloads stopwords (common words to ignore in searches)
- Downloads punkt tokenizer for sentence splitting
Step 15: Verify Installation
# Check all service statuses
sudo systemctl status paperless-webserver
sudo systemctl status paperless-consumer
sudo systemctl status paperless-scheduler
sudo systemctl status paperless-task-queue Access Paperless-ngx at http://YOUR_SERVER_IP:8000
Troubleshooting Bare Metal Installation
Redis Connection Issues
# Test Redis connection
redis-cli ping
# Should respond: PONG
# Check Redis service status
sudo systemctl status redis-server Permission Problems
# Verify ownership of all directories
ls -la /opt/paperless
# Fix permissions if needed
sudo chown -R paperless:paperless /opt/paperless Service Failures
# View detailed logs for a service
journalctl -u paperless-webserver -f
# View all Paperless-related logs
journalctl -u paperless-* --since "1 hour ago" Database Migration Errors
# Re-run migrations
sudo -Hu paperless bash -c "cd /opt/paperless/src && /opt/paperless/venv/bin/python manage.py migrate" Updating Bare Metal Installation
# Stop all services
sudo systemctl stop paperless-webserver paperless-consumer paperless-scheduler paperless-task-queue
# Download new release (replace version number)
cd /opt/paperless
sudo -u paperless curl -O -L https://github.com/paperless-ngx/paperless-ngx/releases/download/vX.X.X/paperless-ngx-vX.X.X.tar.xz
# Extract and overwrite
sudo -u paperless tar -xf paperless-ngx-vX.X.X.tar.xz
sudo -u paperless cp -r paperless-ngx/* .
# Reinstall dependencies
sudo -u paperless /opt/paperless/venv/bin/pip install -r /opt/paperless/requirements.txt
# Run migrations
sudo -Hu paperless bash -c "cd /opt/paperless/src && /opt/paperless/venv/bin/python manage.py migrate"
# Restart services
sudo systemctl start paperless-webserver paperless-consumer paperless-scheduler paperless-task-queue Part 6: Reverse Proxy Setup (HTTPS)
For security and external access, run Paperless-ngx behind a reverse proxy with HTTPS.
Option A: Nginx Reverse Proxy
Step 1: Install Nginx and Certbot
sudo apt update
sudo apt install -y nginx certbot python3-certbot-nginx Step 2: Create Nginx Configuration
Create /etc/nginx/sites-available/paperless:
# Redirect HTTP to HTTPS
server {
listen 80;
server_name documents.yourdomain.com;
location / {
return 301 https://$host$request_uri;
}
}
# HTTPS Server
server {
listen 443 ssl http2;
server_name documents.yourdomain.com;
# SSL certificates (will be configured by Certbot)
ssl_certificate /etc/letsencrypt/live/documents.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/documents.yourdomain.com/privkey.pem;
# Allow large file uploads
client_max_body_size 1000M;
# Timeouts for large operations
proxy_read_timeout 600s;
proxy_send_timeout 600s;
send_timeout 600s;
location / {
proxy_pass http://127.0.0.1:8000;
# Required headers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
} Step 3: Enable the Site
# Create symlink
sudo ln -s /etc/nginx/sites-available/paperless /etc/nginx/sites-enabled/
# Test configuration
sudo nginx -t
# Reload Nginx
sudo systemctl reload nginx Step 4: Obtain SSL Certificate
sudo certbot --nginx -d documents.yourdomain.com Option B: Caddy Reverse Proxy
Caddy automatically handles HTTPS certificates.
Step 1: Install Caddy
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy Step 2: Configure Caddyfile
Edit /etc/caddy/Caddyfile:
documents.yourdomain.com {
reverse_proxy localhost:8000
} Step 3: Restart Caddy
sudo systemctl restart caddy Caddy automatically obtains and renews SSL certificates!
Part 7: Scanner Integration
Paperless-ngx doesnโt directly integrate with scanners. Instead, configure your scanner to save files to the consume folder.
Setting Up the Consume Folder
The consume folder is a โwatchedโ directory. Any PDF, image, or document placed here is automatically:
- Processed by OCR
- Added to your document archive
- Removed from the consume folder
Scanner Configuration Methods
Method 1: Network Share (SMB/CIFS)
Share the consume folder on your network:
# Install Samba
sudo apt install -y samba
# Add share to /etc/samba/smb.conf
[paperless-consume]
path = /opt/paperless/consume
browseable = yes
read only = no
guest ok = no
valid users = scanner_user Then configure your scanner to save to \\SERVER_IP\paperless-consume.
Method 2: FTP Server
Set up an FTP server pointing to the consume folder.
Method 3: Email Integration
Configure Paperless-ngx to fetch documents from email:
# In docker-compose.env or paperless.conf
PAPERLESS_EMAIL_HOST=imap.gmail.com
PAPERLESS_EMAIL_PORT=993
PAPERLESS_EMAIL_HOST_USER=your-email@gmail.com
PAPERLESS_EMAIL_HOST_PASSWORD=your-app-password
PAPERLESS_EMAIL_INBOX_FOLDER=INBOX
PAPERLESS_EMAIL_SECRET=your-secret-for-email Part 8: Backup and Restore
Using the Document Exporter (Recommended)
The document exporter creates a complete backup of all documents and metadata.
Export Documents
# Docker
docker compose exec webserver document_exporter ../export
# Bare metal
sudo -u paperless /opt/paperless/venv/bin/python manage.py document_exporter /opt/paperless/export What gets exported:
- All original documents
- All thumbnails
- Complete database dump (manifest.json)
- Tags, correspondents, document types
- User accounts and permissions
Restore Documents
# Docker (on a fresh installation)
docker compose exec webserver document_importer ../export
# Bare metal
sudo -u paperless /opt/paperless/venv/bin/python manage.py document_importer /opt/paperless/export โ ๏ธ Important: Run the importer on a completely empty Paperless-ngx installation.
Automated Backup Script
Create /opt/paperless/backup.sh:
#!/bin/bash
# Configuration
BACKUP_DIR="/backup/paperless"
DATE=$(date +%Y-%m-%d_%H-%M-%S)
RETENTION_DAYS=30
# Create backup directory
mkdir -p "$BACKUP_DIR"
# Run document exporter
docker compose -f /path/to/docker-compose.yml exec -T webserver document_exporter ../export
# Create archive
tar -czvf "$BACKUP_DIR/paperless-backup-$DATE.tar.gz" /path/to/paperless/export
# Remove old backups
find "$BACKUP_DIR" -name "paperless-backup-*.tar.gz" -mtime +$RETENTION_DAYS -delete
echo "Backup completed: $BACKUP_DIR/paperless-backup-$DATE.tar.gz" Add to crontab for daily backups:
crontab -e
# Add:
0 2 * * * /opt/paperless/backup.sh >> /var/log/paperless-backup.log 2>&1 Part 9: Troubleshooting
Common Issues and Solutions
Documents Not Being Consumed
Problem: Files in consume folder arenโt being processed.
Solutions:
Check permissions:
# Docker docker compose exec webserver ls -la /usr/src/paperless/consume # Ensure USERMAP_UID and USERMAP_GID match your host user id your_usernameEnable polling for network shares:
PAPERLESS_CONSUMER_POLLING=60Check consumer logs:
docker compose logs -f webserver | grep consumer
Permission Denied Errors
Problem: [Errno 13] Permission denied
Solutions:
Set correct UID/GID:
USERMAP_UID=1000 USERMAP_GID=1000Fix folder permissions:
sudo chown -R 1000:1000 ./consume ./data ./media ./export
OCR Not Working
Problem: Documents arenโt searchable after processing.
Solutions:
Install correct language packs:
PAPERLESS_OCR_LANGUAGE=eng+deu+fraCheck OCR logs:
docker compose logs webserver | grep -i ocr
Database Connection Errors
Problem: Canโt connect to PostgreSQL.
Solutions:
Check database container is healthy:
docker compose psVerify database credentials match in all places.
Check database logs:
docker compose logs db
Web Interface Not Loading
Problem: Canโt access the web interface.
Solutions:
Check container status:
docker compose psCheck webserver logs:
docker compose logs webserverVerify port mapping:
docker port paperless-ngx-webserver-1Check firewall:
sudo ufw status sudo ufw allow 8000/tcp
Part 10: Useful Commands Reference
Docker Commands
# Start Paperless-ngx
docker compose up -d
# Stop Paperless-ngx
docker compose down
# View logs
docker compose logs -f
# Restart a specific service
docker compose restart webserver
# Update to latest version
docker compose pull
docker compose up -d
# Run management commands
docker compose exec webserver python manage.py <command>
# Create superuser
docker compose run --rm webserver createsuperuser
# Export documents
docker compose exec webserver document_exporter ../export
# Import documents
docker compose exec webserver document_importer ../export
# Rebuild search index
docker compose exec webserver document_index reindex Environment Variables Reference
| Variable | Description | Default |
|---|---|---|
PAPERLESS_SECRET_KEY | Django secret key | MUST SET |
PAPERLESS_TIME_ZONE | Timezone (e.g., America/New_York) | UTC |
PAPERLESS_OCR_LANGUAGE | OCR language(s) | eng |
PAPERLESS_ADMIN_USER | Admin username | None |
PAPERLESS_ADMIN_PASSWORD | Admin password | None |
PAPERLESS_CONSUMER_POLLING | Polling interval (seconds) | 0 (inotify) |
PAPERLESS_OCR_THREADS | OCR processing threads | Auto |
USERMAP_UID | Host user ID | 1000 |
USERMAP_GID | Host group ID | 1000 |
PAPERLESS_DBHOST | Database hostname | db |
PAPERLESS_DBPORT | Database port | 5432 |
PAPERLESS_DBNAME | Database name | paperless |
PAPERLESS_DBUSER | Database user | paperless |
PAPERLESS_DBPASS | Database password | paperless |
Conclusion
Paperless-ngx is a powerful tool for creating a paperless office environment. With this guide, you should be able to:
- Install Paperless-ngx using Docker or bare metal
- Configure it for your specific needs
- Set up secure remote access with HTTPS
- Integrate scanners and email
- Maintain proper backups
Next Steps
- Start scanning your documents into the consume folder
- Set up tags and correspondents to organize documents
- Configure matching rules for automatic classification
- Set up regular backups to protect your data
Additional Resources
This guide was created by AiCybr. For more self-hosting guides and tutorials, visit aicybr.com.
Comments
Sign in to join the discussion!
Your comments help others in the community.