
Paperless-ngx Document Management on Linux with OCR and Backups
- AuthorKacey H.
- Date
- Time17 minutes
Paperless-ngx turns scanned PDFs and office documents into a searchable archive with tags, correspondents, and full-text OCR. For freelancers and small teams drowning in invoice folders, it is one of the highest leverage self-hosted tools. This guide deploys it with PostgreSQL, Redis, HTTPS, and backups that include media files — not only the database.
Prerequisites
- Linux host with Docker Compose and enough disk for document growth
- DNS for docs.example.com
- Optional scanner workflow that can drop files into a consume folder
Step 1: Create Directories and Secrets
bash
sudo mkdir -p /opt/paperless/{consume,media,export,data}
cd /opt/paperless
SECRET=$(openssl rand -hex 32)
DBPASS=$(openssl rand -hex 16)
tee .env >/dev/null <<EOF
PAPERLESS_SECRET_KEY=$SECRET
PAPERLESS_URL=https://docs.example.com
PAPERLESS_TIME_ZONE=Europe/Berlin
PAPERLESS_OCR_LANGUAGE=eng+deu
POSTGRES_PASSWORD=$DBPASS
EOF
chmod 600 .envStep 2: Docker Compose Stack
bash
tee docker-compose.yml >/dev/null <<'EOF'
services:
broker:
image: redis:7-alpine
restart: unless-stopped
db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: paperless
POSTGRES_USER: paperless
POSTGRES_PASSWORD: \${POSTGRES_PASSWORD}
volumes:
- pgdata:/var/lib/postgresql/data
webserver:
image: ghcr.io/paperless-ngx/paperless-ngx:2.14.7
restart: unless-stopped
depends_on:
- db
- broker
ports:
- "127.0.0.1:8000:8000"
env_file: .env
environment:
PAPERLESS_REDIS: redis://broker:6379
PAPERLESS_DBHOST: db
PAPERLESS_DBUSER: paperless
PAPERLESS_DBPASS: \${POSTGRES_PASSWORD}
PAPERLESS_DBNAME: paperless
volumes:
- ./data:/usr/src/paperless/data
- ./media:/usr/src/paperless/media
- ./export:/usr/src/paperless/export
- ./consume:/usr/src/paperless/consume
volumes:
pgdata:
EOF
docker compose up -d
docker compose psStep 3: Create Superuser and TLS Proxy
bash
docker compose exec webserver createsuperuser
sudo tee /etc/nginx/sites-available/paperless >/dev/null <<'EOF'
server {
listen 80;
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-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
EOF
sudo ln -sf /etc/nginx/sites-available/paperless /etc/nginx/sites-enabled/paperless
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d docs.example.com --redirectStep 4: Consume Folder Workflow
bash
# Drop PDFs into the consume directory; Paperless OCR processes them automatically
cp ~/Downloads/invoice.pdf /opt/paperless/consume/
docker compose logs -f webserver | grep -i consumeStep 5: Export and Backup
bash
docker compose exec webserver document_exporter /usr/src/paperless/export
tar -czf /var/backups/paperless-export-$(date +%F).tar.gz -C /opt/paperless export media data
docker compose exec -T db pg_dump -U paperless paperless | gzip > /var/backups/paperless-db-$(date +%F).sql.gzProduction Checklist
- Back up media and database together; OCR text without files is incomplete.
- Keep PAPERLESS_SECRET_KEY safe — losing it breaks sessions and signed URLs.
- Restrict registration and use strong admin MFA via reverse-proxy SSO if available.
- Watch consume-folder permissions for scanner/NAS drop users.
- Test a document_exporter restore on a staging host before you rely on it.
"A document archive earns trust only when OCR, access control, and restore drills are as intentional as the upload workflow."



