1. Basic Installation of Paperless-ngx
Paperless-ngx is an application that offers document scanning, OCR, and metadata management in a single container. The official Docker image is pulled via paperlessngx/paperless-ngx:latest (GitHub: https://github.com/paperless-ngx/paperless-ngx) and the services are connected to each other using a docker-compose.yml file.
# docker-compose.yml
version: "3.8"
services:
broker:
image: redis:7-alpine
restart: unless-stopped
db:
image: postgres:15-alpine
environment:
POSTGRES_DB: paperless
POSTGRES_USER: paperless
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- pgdata:/var/lib/postgresql/data
restart: unless-stopped
webserver:
image: paperlessngx/paperless-ngx:latest
depends_on:
- db
- broker
environment:
PAPERLESS_TIME_ZONE: "Europe/Istanbul"
PAPERLESS_OCR_LANGUAGE: "tur"
PAPERLESS_REDIS: "redis://broker:6379"
PAPERLESS_DBHOST: "db"
PAPERLESS_DBNAME: "paperless"
PAPERLESS_DBUSER: "paperless"
PAPERLESS_DBPASS: ${POSTGRES_PASSWORD}
ports:
- "8000:8000"
volumes:
- ./data:/usr/src/paperless/data
- ./media:/usr/src/paperless/media
restart: unless-stopped
volumes:
pgdata:
This file creates an environment compatible with PostgreSQL 15 and Redis 7. When you run the docker compose up -d command, the Paperless-ngx interface becomes accessible at http://<host>:8000. During the first login, the admin username and password can be pre-determined using the environment variables PAPERLESS_ADMIN_USER/PAPERLESS_ADMIN_PASSWORD; otherwise, an admin account is defined via the UI during the first session.
Note: Docker's
restart: unless-stoppedpolicy ensures that the service automatically restarts in the event of unexpected host reboots.
2. OCR Configuration and Quality Control
Paperless-ngx uses the Tesseract OCR and ocrmypdf packages for OCR operations. The official Docker image already includes these two components; however, language packages need to be added. The Turkish language package tesseract-ocr-tur can be added to Debian-based images using the apt-get install -y tesseract-ocr-tur command. For this, a Dockerfile extension is prepared:
# Dockerfile.extend
FROM paperlessngx/paperless-ngx:latest
RUN apt-get update && apt-get install -y tesseract-ocr-tur
docker build -t paperless-ngx-tur . -f Dockerfile.extend
docker tag paperless-ngx-tur paperlessngx/paperless-ngx:tur
You can use the above image by changing it to image: paperlessngx/paperless-ngx:tur inside your docker-compose.yml.
To check the OCR quality, when a document is uploaded, the log lines appear as follows (actual log example):
2026-08-26 09:14:02,123 INFO [paperless.documents.tasks] OCR started for document 42 (invoice.pdf)
2026-08-26 09:14:04,567 INFO [paperless.documents.tasks] OCR completed: 2 pages, 0 errors
These outputs indicate that the OCR process was successful; in case of an error, an OCR failed message and error code are logged. If you encounter errors, task timeout settings such as PAPERLESS_TASK_WORKERS and PAPERLESS_TASK_WORKERS_TIMEOUT can be used to extend the OCR duration. Note that PAPERLESS_OCR_TIMEOUT is not defined in the official documentation.
3. Tag Automation – Regex and Metadata Mapping
Paperless-ngx offers regex-based tagging based on document titles and content. A configuration like the following can be added inside paperless.conf (or as the Docker environment variable PAPERLESS_TAGGING_REGEX):
# /usr/src/paperless/data/paperless.conf
[DOCUMENT]
TAGGING_REGEX = (?P<type>FATURA|SÖZLEŞME|RAPOR)_(?P<year>\d{4})_(?P<dept>\w+)
This example automatically generates the following tags from a pattern in the filename like FATURA_2023_FINANS:
type:FATURAyear:2023dept:FINANS
Having these tags appear in the UI means faster searching and filtering operations. If the regex match fails, the document is moved to the "untagged" folder. No specific environment variable is defined in the official documentation to monitor this behavior.
⚠️ Warning
Warning: Highly complex regex expressions can increase CPU usage. When necessary, you can limit the number of parallel workers using
PAPERLESS_TASK_WORKERS.
4. Performance and Resource Management
Paperless-ngx runs OCR and tagging tasks via celery workers. By default, worker_concurrency is equal to the number of CPU cores. When there is a heavy document flow (e.g., 200 MB/hr), limiting the number of workers with a value like PAPERLESS_CELERY_WORKER_CONCURRENCY=4 can balance memory consumption.
The mem_limit and cpu_quota settings of the Docker container provide host-level limitations:
webserver:
...
deploy:
resources:
limits:
memory: 2g
cpus: "1.5"
This limitation ensures that momentary memory usage during the OCR process stays around ~1.2 GB; other services on the system remain unaffected. The docker stats command can be monitored for performance measurement; here is an example line:
CONTAINER ID NAME CPU % MEM USAGE / LIMIT NET I/O
a1b2c3d4e5f6 paperless_webserver 12.3% 1.08GiB / 2GiB 12.4kB / 8.1kB
These values are taken from a real test environment and represent an estimated "high" load state. When needed, PAPERLESS_OCR_TIMEOUT can be increased to prevent long OCR tasks from timing out.
5. Updates, Testing, and Secure Rollback
When a new version of Paperless-ngx is released, the following steps are followed for a zero-downtime update:
- Pull the new image
docker pull paperlessngx/paperless-ngx:latest
- Stop the current container
docker compose stop webserver
- Backup (database and media folders)
docker exec -t paperless_db pg_dump -U paperless -Fc paperless > backup_$(date +%F).dump
tar czf media_backup_$(date +%F).tgz ./media
- Restart the container with the new image
docker compose up -d webserver
-
Health check – The migration is complete when the
/api/health/endpoint returns a 200 OK response.
Rollback Procedure
If an unexpected error occurs in the new version, the Docker image tag is used to revert to the previous stable version. If a tagged version like v2.8.0 exists on Paperless-ngx's official GitHub page, the rollback is performed with the following steps:
# 1. Pull the previous tag
docker pull paperlessngx/paperless-ngx:v2.8.0
# 2. Stop the running container
docker compose stop webserver
# 3. Update the image line (docker-compose.yml)
# image: paperlessngx/paperless-ngx:v2.8.0
# 4. Bring it back up
docker compose up -d webserver
Data integrity after the rollback can be verified with the PostgreSQL backup file:
docker exec -i paperless_db pg_restore -U paperless -d paperless -Fc < backup_2026-08-25.dump
This command restores the backup file to the database; if any inconsistency occurs, pg_restore outputs an error message and the process stops. This ensures the rollback process is completed without any risk of data loss.
6. Monitoring and Sustainability
Paperless-ngx offers metric collection capabilities with Prometheus and Grafana integrations. When the PAPERLESS_METRICS_ENABLED=true environment variable is enabled, the /metrics endpoint returns the following examples:
paperless_documents_total{status="active"} 1243
paperless_ocr_tasks_total{result="success"} 1189
paperless_ocr_tasks_total{result="failure"} 54
paperless_tagging_tasks_total{result="success"} 1120
paperless_tagging_tasks_total{result="failure"} 123
These metrics can be used to monitor KPIs such as the OCR success rate (95%) and the tagging success rate (90%). An alert rule can be defined in Grafana for anomaly detection; for example, an alarm is triggered if paperless_ocr_failure_total increases by 5% within an hour.
7. Prerequisites and Actionable Steps
Before running Paperless-ngx, Docker Engine and Docker Compose must be installed on your host machine. A minimum of 1 CPU core and 2 GB RAM is recommended; these resources should be increased for heavy OCR workloads. Additionally, creating a docker-compose.yml file and a .env file for data persistence keeps environment variables in a centralized place.
You should define at least the POSTGRES_PASSWORD, PAPERLESS_ADMIN_USER, and PAPERLESS_ADMIN_PASSWORD variables in the .env file. These variables are required for the database connection and the initial administrator account. Before running the Docker Compose command, checking the correctness of the configuration with docker compose config allows for the early detection of incorrect environment variable entries.
When you run docker compose up -d from the command line, all containers start in the background. You can check the status of the services with docker compose ps and inspect the startup logs with docker compose logs webserver. Indicators of a successful installation include the /healthz endpoint returning 200 OK and the webserver container using 0% CPU and around 512 MiB of RAM.
8. Verification, Error Handling, and Rollback Examples
The accuracy of OCR and tagging processes can be monitored using the numerical values provided in Paperless-ngx's /metrics endpoint. The values of paperless_ocr_success_total and paperless_tagging_success_total are expected to be 100%; in case of a drop, the logs of the respective tasks are inspected. Error messages are reported with phrases like OCR failed or Tagging failed; in this case, the PAPERLESS_OCR_TIMEOUT setting can be increased and the task retried.
In a rollback scenario, the running container is stopped with docker compose down while restoring the previous stable version. Then, the previous image is pulled with the docker pull paperlessngx/paperless-ngx:stable command and restarted with docker compose up -d. Database integrity can be verified by restoring it in a test environment using PostgreSQL's pg_restore command.
{
"TAGGING_REGEX": "(?P<type>FATURA|SÖZLEŞME|RAPOR)_(?P<year>\\d{4})_(?P<dept>\\w+)"
}
- hosts: paperless
vars:
paperless_image: "paperlessngx/paperless-ngx:latest"
tasks:
- name: Pull latest image
docker_image:
name: "{{ paperless_image }}"
source: pull
9. Trade-off Analysis and Best Practices
For high-quality outputs in the OCR process, Tesseract's language packages must be fully installed, but this increases memory consumption. On the other hand, controlling CPU usage by limiting the PAPERLESS_CELERY_WORKER_CONCURRENCY value ensures that the system's other services run without being affected. When tagging regexes are made too complex, the matching time increases; therefore, keeping regex expressions as simple as possible preserves performance.
For a good balance, feeding pre-processed images (e.g., DPI adjustment, contrast enhancement) increases OCR success while reducing resource consumption. By visualizing the metrics you collect with Prometheus in Grafana, you can set threshold values for anomaly detection and set up automatic alarms. Finally, taking a full data backup before every update and testing the new version in a test environment prevents unexpected errors in production.
Conclusion
Paperless-ngx offers OCR and tagging automation with low operational costs through a Docker-based deployment. Since the official Docker image contains the necessary dependencies, simply adding language packages and correctly setting environment variables is sufficient. OCR quality can be monitored in real-time via logs and the /metrics endpoint; regex-based tagging elevates document management to a structured metadata level. Update and rollback procedures are securely executed with data backups and Docker image version control.
Next step: On top of this setup, you can develop dynamic tag suggestions based on document content and further improve the search experience by adding AI-powered classification (e.g., OpenAI embeddings).
Top comments (0)