Getting Paper Out of Your Life Without Losing Control of It
Every scanned receipt, tax document, insurance policy, and utility bill you have ever saved exists somewhere – a drawer, a folder, a desktop directory with a name like “misc_2022_FINAL.” Paperless-NGX is an open-source document management system that replaces that chaos with a self-hosted web interface where documents are automatically tagged, OCR-processed, and made fully searchable. You own the server. You own the data. Nothing goes to a third-party cloud.
Paperless-NGX is a community-maintained fork of the original Paperless project, built to run on a home server, a VPS, or a Raspberry Pi. It ingests documents through a consume folder, runs optical character recognition on them automatically, and lets you search the full text of any file you have ever added. It supports PDFs, images, and plain text files, and it can be configured to auto-assign tags, correspondents, and document types based on rules you write yourself.
This guide walks through a Docker Compose deployment on a Linux server.

What You Need Before You Start
The requirements are modest. You need a Linux server – physical or virtual – with Docker and Docker Compose installed. Paperless-NGX officially supports amd64 and arm64 architectures, so a Raspberry Pi 4 or 5 with 4GB of RAM is a realistic option. For a household document archive, even a low-powered VPS with 2GB of RAM will handle the workload without strain, though OCR processing on large image-heavy PDFs will take longer on constrained hardware.
You also need a dedicated directory on the host machine to store three persistent folders: the media directory where processed documents live, the data directory for the database and configuration, and the consume directory where you drop new files for ingestion. These directories should be backed up independently of the container. If you ever rebuild the container, those folders are what preserve your archive. Assign them readable permissions so the container user can write to them without running the service as root.
Optionally, set up a reverse proxy like Nginx Proxy Manager or Caddy in front of Paperless-NGX if you want to expose it with a domain name and HTTPS. Running it on a local network without TLS is fine for home use, but any public-facing deployment should be protected. Port 8000 is the default internal port the application serves on.
Deploying With Docker Compose
Paperless-NGX ships an official Docker Compose configuration that includes the web application, a Redis broker for task queuing, and a PostgreSQL database container. Pull the example compose file from the project’s GitHub repository or the official documentation at docs.paperless-ngx.com. The file defines four services: broker (Redis), db (PostgreSQL), webserver, and gotenberg plus tika if you want support for converting Office documents and email files. For a basic PDF-only setup, gotenberg and tika are optional.

Inside the docker-compose.env file, set the variables that control your instance. PAPERLESS_SECRET_KEY should be a long random string – generate one with openssl rand -hex 32. Set PAPERLESS_URL to the address you will access the interface from, whether that is an IP address or a domain. Set PAPERLESS_TIME_ZONE to your local timezone using standard tz database format. PAPERLESS_OCR_LANGUAGE defaults to English; add additional language codes separated by plus signs if your documents use other languages. The PAPERLESS_CONSUMPTION_DIR and PAPERLESS_MEDIA_ROOT variables should point to the host directories you created earlier using bind mount paths in the volumes section.
Once the environment file is configured, run docker compose up -d from the directory containing the compose file. The first startup takes a few minutes as the database initializes and the OCR language packs download. After that, create the admin user by running docker compose exec webserver python3 manage.py createsuperuser and following the prompts. Log into the interface at your server’s IP on port 8000, and the dashboard will be empty, ready for documents.
Configuring Automatic Tagging and Document Rules
The real power of Paperless-NGX is its rules engine. Under Settings, you can define correspondents – the people or organizations associated with documents – and document types like invoices, statements, or contracts. Once you have those categories set up, navigate to Mail Rules or the consumption templates section and define matching conditions. A rule can say: if the document content contains the phrase “electric utility” and the filename includes “bill,” assign the correspondent “Power Company” and the document type “Utility Bill” and apply the tag “expenses.” The match happens automatically every time a new document is consumed.
The consume folder is the simplest ingestion method. Any file you drop into it is picked up within seconds, processed through OCR, and filed in the archive. For a household scanner or a phone scanning app, you can set the output folder directly to the consume directory if it is mounted over a network share. Paperless-NGX also supports consuming documents via email – configure an IMAP account under Settings and it will pull attachments from specified mailboxes on a schedule, which works well for utility bills and bank statements delivered digitally.
Saved views let you build filtered dashboards on the front page. Create a view called “Needs Review” that shows documents without a correspondent assigned, or a view called “This Year’s Taxes” filtered by tag and date range. These are persistent and appear as quick-access tiles on the main dashboard, so your most frequently checked document sets are one click away from anywhere in the interface.

After a few weeks of regular use, the pattern becomes clear: drop something into the consume folder, let OCR and the rules engine do their work, and retrieve it months later with a full-text search query. No filing cabinet. No ambiguous folder names. No remembering which subfolder holds the 2023 water bill – just type “water” and it is there, with the original scan attached and every field already filled in.





