Deploy Paperless-ngx on Pethost in one click
A document archive with OCR and full-text search
What happens
- You sign in to Pethost or make an account, with a passkey, GitHub or Google.
- No machine yet? You pick a plan, and we prepare one for you. The link waits in your browser until it is ready.
- New project opens at the app. You fill in what it asks for and click Create project: Admin password.
- In a minute or two the app is live at its own address with HTTPS. Its secrets are made for it at random, and its data is in the nightly backup.
- It is a project like any other: its compose.yaml, its .env, its logs and a terminal are in the panel, and your agent can change it, roll it back or restore it.
First steps
Sign in as admin with the password you gave. Documents are read as English until you change the OCR language under Configuration.
What it runs
The template is this compose.yaml and the variables it writes into the project’s .env. Pethost runs the file as it is written.
services:
broker:
image: valkey/valkey:9-alpine
restart: unless-stopped
volumes:
- redisdata:/data
healthcheck:
test: ["CMD-SHELL", "valkey-cli ping | grep -q PONG"]
interval: 5s
timeout: 3s
retries: 10
db:
image: postgres:18
restart: unless-stopped
environment:
POSTGRES_DB: paperless
POSTGRES_USER: paperless
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- pgdata:/var/lib/postgresql
healthcheck:
# Over TCP: the server of the first start's initialisation listens on
# the socket alone, and is not the one the app will reach.
test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -U paperless -d paperless"]
interval: 5s
timeout: 3s
retries: 20
webserver:
image: ghcr.io/paperless-ngx/paperless-ngx:3.3
restart: unless-stopped
depends_on:
db:
condition: service_healthy
broker:
condition: service_healthy
environment:
PAPERLESS_REDIS: redis://broker:6379
PAPERLESS_DBENGINE: postgresql
PAPERLESS_DBHOST: db
PAPERLESS_DBPASS: ${POSTGRES_PASSWORD}
PAPERLESS_URL: ${PAPERLESS_URL}
PAPERLESS_SECRET_KEY: ${PAPERLESS_SECRET_KEY}
# The first start makes this superuser, so no sign-up page is left open.
PAPERLESS_ADMIN_USER: admin
PAPERLESS_ADMIN_PASSWORD: ${ADMIN_PASSWORD}
# TLS ends at the machine's proxy, which says so in X-Forwarded-Proto.
PAPERLESS_PROXY_SSL_HEADER: '["HTTP_X_FORWARDED_PROTO", "https"]'
volumes:
- data:/usr/src/paperless/data
- media:/usr/src/paperless/media
- export:/usr/src/paperless/export
- consume:/usr/src/paperless/consume
healthcheck:
# The image's own check, with time for the first start's migrations.
test: ["CMD", "curl", "-fs", "-S", "-L", "--max-time", "2", "http://localhost:8000"]
interval: 30s
timeout: 10s
retries: 5
start_period: 180s
volumes:
redisdata:
pgdata:
data:
media:
export:
consume: