Skip to main content

Self-Host Paperless-ngx with Docker Compose

Paperless-ngx needs Redis in every setup. Redis is the queue between the web server and the background workers that run OCR, so without it no document is ever processed. The database is SQLite by default. For anything beyond a test install use PostgreSQL 14 or newer, or MariaDB. Two directories must be persisted: /usr/src/paperless/media holds the documents themselves, and /usr/src/paperless/data holds the search index and the auto-tagging model.

Before using the one-click template, here is a minimal Docker Compose example for self-hosting Paperless-ngx.

If you're new to Docker Compose, check out our guide on how to self-host a Docker Compose app. More stacks are in our Docker Compose library.

Self-host Paperless-ngx with Docker Compose (minimal)​

services:
broker:
image: valkey/valkey:9-alpine
volumes:
- redisdata:/data

db:
image: postgres:18
environment:
POSTGRES_DB: paperless
POSTGRES_USER: paperless
POSTGRES_PASSWORD: changeme
volumes:
- pgdata:/var/lib/postgresql

webserver:
image: ghcr.io/paperless-ngx/paperless-ngx:latest
ports:
- "8000:8000"
environment:
PAPERLESS_REDIS: redis://broker:6379
PAPERLESS_DBENGINE: postgresql
PAPERLESS_DBHOST: db
PAPERLESS_DBPASS: changeme
PAPERLESS_SECRET_KEY: change-me-to-a-long-random-string
PAPERLESS_URL: http://localhost:8000
PAPERLESS_OCR_LANGUAGE: eng
volumes:
- data:/usr/src/paperless/data
- media:/usr/src/paperless/media
- ./consume:/usr/src/paperless/consume
- ./export:/usr/src/paperless/export
depends_on:
- db
- broker

volumes:
data:
media:
pgdata:
redisdata:

This follows the upstream docker-compose.postgres.yml. Valkey is a drop-in Redis replacement. PAPERLESS_DBNAME and PAPERLESS_DBUSER default to paperless, so they are left out here. Set PAPERLESS_DBENGINE explicitly. The docs require it for PostgreSQL and MariaDB.

Set PAPERLESS_URL to the address you open in the browser, with no trailing slash. Paperless adds this origin to its CSRF trusted origins. Behind an HTTPS reverse proxy, a missing or wrong value makes logins fail with a CSRF error.

On the first visit the web UI asks you to create an admin account. Or set PAPERLESS_ADMIN_USER and PAPERLESS_ADMIN_PASSWORD before the first boot.


Deploy Paperless-ngx on Hostim.dev (one-click)​

Paperless-ngx scans, OCRs and indexes your documents so you can search every PDF and paper letter you own. On Hostim.dev the template runs the official image against a managed PostgreSQL database and a managed Redis, mounts both volumes, creates the admin account, and sets PAPERLESS_URL to the project domain.

πŸ“„ Your documents on EU servers, full-text searchable from any browser.

Try it Yourself

Guest project runs for 1 hour. Log in to save and extend to 5 days.

Why host Paperless-ngx on Hostim.dev?​

  • One-click Docker deployment, no server setup
  • Managed PostgreSQL and Redis, both wired in
  • Persistent volumes for documents and the search index
  • Admin account and secret key generated at deploy time
  • Automatic HTTPS and domain
  • Real-time logs and metrics

What's included​

ResourceDetails
Appghcr.io/paperless-ngx/paperless-ngx:latest image
DatabaseManaged PostgreSQL
RedisManaged Redis (task broker)
Volumes/usr/src/paperless/media, /usr/src/paperless/data
DomainFree *.hostim.dev subdomain
SSLLet's Encrypt (auto-enabled)
Port8000

How to Deploy​

  1. Go to your Hostim.dev dashboard.
  2. Click Create Project β†’ Use a Template.
  3. Select Paperless-ngx.
  4. Choose a resource plan.
  5. Deploy.

First steps after deploy​

  1. Log in as admin. The password is in the PAPERLESS_ADMIN_PASSWORD variable of the app. Change it under My Profile. Paperless creates this user only on the first boot, so changing the variable later does not change the password.
  2. Set your OCR language. The template OCRs in English. For German letters set PAPERLESS_OCR_LANGUAGE to deu, or eng+deu for both, and redeploy. English, German, French, Italian and Spanish ship with the image. Other languages also need PAPERLESS_OCR_LANGUAGES (for example nld) so the container downloads them on boot.
  3. Upload a document by dragging it onto the dashboard. Progress shows in the file tasks panel. OCR of large scans takes a while on a small plan.
  4. Point your own domain at the app under Networking β†’ Domains, then set PAPERLESS_URL to match and redeploy.

The consume folder is not on a volume in this template. Upload through the web UI, the mobile apps or the REST API instead of dropping files into it.


Frequently asked questions

Does Paperless-ngx need Redis?

Yes, in every setup. Redis is the Celery message broker between the web server and the background workers. The workers run consumption, OCR, indexing and scheduled tasks, so without Redis uploads stay queued and are never processed. Valkey works as a drop-in replacement.

Which database should I use for Paperless-ngx: SQLite, PostgreSQL or MariaDB?

SQLite is the default and works for a small single-user archive. PostgreSQL (version 14 or newer) is the most common production choice and what the upstream compose examples lead with. MariaDB is also supported. Whichever you pick, set PAPERLESS_DBENGINE explicitly to postgresql or mariadb.

What is the minimal docker-compose.yml for Paperless-ngx?

Three services: a Redis or Valkey broker, a postgres database, and the ghcr.io/paperless-ngx/paperless-ngx webserver with PAPERLESS_REDIS, PAPERLESS_DBENGINE, PAPERLESS_DBHOST, PAPERLESS_SECRET_KEY and PAPERLESS_URL set, plus volumes at /usr/src/paperless/data and /usr/src/paperless/media. The full file is in the section above.

Where does Paperless-ngx store documents in Docker?

Original files, archived PDFs and thumbnails go to /usr/src/paperless/media. The full-text search index and the classifier model go to /usr/src/paperless/data. Tags, correspondents, document types and users live in the database. Back up the media volume and the database together.

Why do I get a CSRF error when logging in to Paperless-ngx?

Usually PAPERLESS_URL does not match the address in the browser. Paperless adds PAPERLESS_URL to its CSRF trusted origins, and behind an HTTPS reverse proxy that is what lets the login form through. The value must include the scheme, match the host exactly and have no trailing slash. After adding a custom domain, update PAPERLESS_URL and restart the container.

How do I change the OCR language in Paperless-ngx?

Set PAPERLESS_OCR_LANGUAGE to a Tesseract language code, such as deu for German or eng+deu for both. The Docker image ships English, German, French, Italian and Spanish. For any other language, also list it in PAPERLESS_OCR_LANGUAGES so the container installs it at startup.

Can Paperless-ngx import Word and email files?

Only with Apache Tika and Gotenberg running alongside it. Word, Excel and .eml files need both, and office files also need PAPERLESS_TIKA_ENABLED=true. Without them Paperless handles PDFs, images and plain text. The Hostim template does not include Tika or Gotenberg.

How do I update Paperless-ngx in Docker?

Run docker compose pull and docker compose up -d. Database migrations run automatically when the container starts. On Hostim, redeploy the app. Back up the database and the media volume first, or run the built-in document_exporter, because migrations are not reversible.


Alternatives​

  • Papra β€” lighter document archive with fewer moving parts
  • Mayan EDMS β€” heavier, with workflows and document versioning
  • Nextcloud β€” general file sync, with OCR through apps

Source + Docs​


Looking for something else? Browse all templates β†’


Try it now​

Deploy Paperless-ngx Now – in less than 60 seconds