# Running paperless-ngx rootless: the 11notes image and its real trade-offs

> The 11notes/docker-paperless-ngx image wraps paperless-ngx to run as UID/GID 1000 without SUID, but it ships with a limited OCR language set and no latest tag. This review covers the mechanics, the commands, and the cases where the official image is the better pick.

**11notes/docker-paperless-ngx** — Run paperless-ngx rootless by default (no SUID)!

- Repository: https://github.com/11notes/docker-paperless-ngx
- Stars: 26 · Forks: 3
- Language: Python
- License: MIT
- Published: 2026-08-27 · Updated: 2026-08-27 · Language: en
- Canonical page: https://hysenlabs.com/projects/11notes-docker-paperless-ngx

## What this image changes and who it is for

The official paperless-ngx container runs as root by default. The 11notes image changes that: it runs the application as UID 1000 and GID 1000, with a user named docker and a home directory of /paperless-ngx. The README states this is done without SUID, meaning no setuid binaries are used to gain privileges. This is aimed at operators who run containers with a rootless runtime, or who enforce non-root execution as a security policy. It is also for people who want a single image that is updated automatically via CI/CD, has a health check, and is scanned for CVEs before and after publishing. If you already run paperless-ngx and are happy with the official image, this is a drop-in replacement with a different user model, not a different application.

## Rootless mechanics: s6, UID/GID, and the absence of SUID

The image uses s6 as its process supervisor. s6 starts and monitors the paperless-ngx processes, which is a common pattern in multi-process container images. The rootless claim rests on two things: the container runs as UID/GID 1000, and no SUID binaries are present. SUID binaries are a classic privilege escalation vector, so their absence is a concrete security improvement over images that need root to start. The README links to a separate RTFM document that explains how to change the default UID/GID, but it does not give the exact commands. That means you have to follow an external guide if your host uses a different user ID. The image also has a health check, but the README does not specify what the check does or how often it runs. That is a gap: you cannot verify the check's behavior from the material alone.

## Volumes and data layout: what to mount where

The image expects six volumes, all under /usr/src/paperless. The consume directory is where you drop documents to be processed. The originals, archive, and thumbnails directories hold the imported, processed, and preview files. The data directory stores internal app files and configs. The export directory is for document exports. This layout matches the official paperless-ngx structure, so migrating from the official image should be straightforward: you can point the same volumes at this image. However, because the image runs as UID 1000, those volumes must be writable by that user. If your existing volumes are owned by root, you will need to adjust ownership or use the -unraid or -nobody variants. The README does not give a chown command, so you have to plan that yourself.

## Getting it running: compose file and environment variables

The README provides a docker-compose example. It defines a service named paperless-ngx that depends on postgres and redis, both with health conditions. The image tag in the example is 11notes/paperless-ngx:3.1.0, though the latest release listed is v2.1.0, which is a discrepancy you should check before using the example verbatim. The environment variables include TZ, PAPERLESS_REDIS, PAPERLESS_DBPASS, PAPERLESS_CONSUMER_POLLING, PAPERLESS_CONSUMER_POLLING_DELAY, PAPERLESS_CONSUMER_POLLING_RETRY_COUNT, and PAPERLESS_OCR_SKIP_ARCHIVE_FILE. The compose snippet is truncated at PAPERLESS_C, so you will need to consult the full README or the repository for the complete file. Pull commands are given for three registries: Docker Hub, ghcr.io, and quay.io. The image also supports a DEBUG environment variable that activates debug options for both the container and the app, if available.

## Tag policy: no latest, but semver and rolling

The image deliberately has no latest tag. The author argues that latest is a bad habit because new releases can introduce breaking changes. Instead, you can use short semver tags like :3 or :3.1, which update to the latest minor or major version but stay within that line. There is also a :rolling tag for people who want the bleeding edge, with a warning that it may include breaking changes or security issues. This is a clear, opinionated policy. For production use, pinning to a full version like :3.1.0 is the safest choice. The trade-off is that you must actively track releases and update your tag manually. The README advises checking the releases page for breaking changes before updating, which is practical advice but also a burden for operators who prefer automatic updates.

## The OCR language limitation is a real constraint

The README contains a caution that is easy to miss: because the image is rootless, it only works with OCR in English, German, French, Italian, and Spanish. If you need another language, you must fork the image and install the tesseract-ocr-{LANGUAGE} package yourself. This is a direct consequence of running without root: you cannot install packages at runtime. For a document management system, OCR language support is a core feature. If you scan documents in, say, Portuguese or Japanese, this image is not suitable out of the box. The official image, which runs as root, likely includes more languages, but the README does not specify the official image's language set. This limitation alone may be enough to disqualify the image for many users.

## How this compares to the official paperless-ngx image

The README names paperlessngx/paperless-ngx as the parent image. The 11notes image builds on top of it, adding the rootless user, s6, and the CI/CD pipeline. The official image runs as root, which simplifies volume permissions and allows installing extra packages, but it also means the container has root privileges inside the container. The 11notes image trades that flexibility for a reduced attack surface. The official image also has a latest tag and likely a broader OCR language set, though the README does not confirm that. The 11notes image adds the -unraid and -nobody variants to adjust UID/GID for specific host environments. If you need the ability to install arbitrary tesseract languages or you rely on the official image's update cadence, the official image is the safer choice. If you value rootless execution as a security boundary and your OCR needs are within the five supported languages, the 11notes image is a meaningful improvement.

## Maintenance, licensing, and what to verify before adopting

The image is licensed under MIT, which is permissive, but the README includes a clear disclaimer: use at your own risk, always make backups before updating, and check the releases for breaking changes. The project is not archived and had recent releases, with the last push in August 2026. The CI/CD pipeline is described as secure and pinned, and the image is automatically scanned for CVEs before and after publishing. However, the README does not provide the actual scan reports or a link to them, so you cannot verify the results without pulling the image and inspecting it. The tag discrepancy between the compose example (3.1.0) and the latest release (v2.1.0) is a red flag: either the README is ahead of the releases or the example is outdated. Before adopting, you should check the actual tags on the registry, read the release notes for the version you plan to use, and confirm that the health check works in your environment. The rootless design is a genuine security benefit, but it comes with the OCR language limit and the manual update process. For a home lab or a small business with English or German documents, this image is a solid choice. For a multi-language deployment, it is the wrong tool unless you are prepared to fork it.

## Conclusion

Adopt this image if you want paperless-ngx running as a non-root user (1000:1000) with s6 supervision, a built-in health check, and a pinned CI/CD build pipeline, and if your OCR needs are covered by EN, DE, FR, IT, or ES. Do not use it if you need OCR in other languages, because the rootless design prevents installing extra tesseract packages without forking the image. Before adopting, verify the release notes for breaking changes, check the CVE scan results for the specific tag you plan to use, and confirm that your volume permissions match UID/GID 1000 (or use the -unraid or -nobody variants if your host requires different IDs). The lack of a latest tag is a deliberate safety feature, but it means you must actively choose a semver tag and plan updates manually.

## FAQ

### How do you set up Paperless-ngx on Docker using this image?

Use the 11notes/paperless-ngx:3.2.1 image in a compose file named dms, with depends_on entries that wait for postgres and redis to report condition service_healthy. Mount the consume, originals, archive, thumbnails, data and export paths, and supply PAPERLESS_SECRET_KEY and PAPERLESS_DBPASS yourself.

### Is Paperless-ngx any good, according to this image's author?

The README does not rate the application. It argues for the image on five points: it runs rootless as 1000:1000, it is auto updated via CI/CD, it has a health check, it is scanned for CVEs before and after publishing, and it is built through a secure and pinned CI/CD process.

### Is there a Paperless-ngx app behind this container image?

The image wraps the upstream application, whose parent image is paperlessngx/paperless-ngx, and it runs that application under s6 supervision. The repository itself is the container build: rootfs/, arch.dockerfile, compose.yml and project.md at the top level.

### What are some alternatives to Paperless-ngx in this image?

The README names no alternative application. It compares the image with the official paperless-ngx image, noting that because this one is rootless it ships OCR for EN, DE, FR, IT and ES only, and the fix for other languages is to fork the image and install the tesseract-ocr-{LANGUAGE} package.

## Sources

- [Official README](https://github.com/11notes/docker-paperless-ngx#readme)
- [Project repository](https://github.com/11notes/docker-paperless-ngx)
- [Release notes](https://github.com/11notes/docker-paperless-ngx/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/11notes-docker-paperless-ngx
