Self-hosting paperless-ngx with PostgreSQL on an Ubuntu Server

Self-hosting paperless-ngx with PostgreSQL on an Ubuntu Server

Jonas Scholz - Co-Founder von sliplane.ioJonas Scholz
7 min

Looking for a self-hosted, paperless document management solution that's lightweight and easy to maintain? paperless-ngx paired with PostgreSQL on an Ubuntu Linux server makes it simple, inexpensive, and secure!

This step-by-step guide shows exactly how you can deploy your own paperless-ngx instance, complete with automatic HTTPS provided by Caddy.

Before you continue, you'll need:

  • An Ubuntu Linux server accessible via SSH (recommended: Hetzner Cloud, or any server with public IP and SSH login).
  • Basic knowledge of SSH command-line usage.

Step 1: Update Your Ubuntu Server

First, ensure your Ubuntu server is secure and updated:

sudo apt-get update
sudo apt-get upgrade -y

Your system is now up-to-date and ready for setup.

Step 2: Configure and Secure UFW Firewall

Let's secure your server by configuring the Ubuntu firewall (UFW). We'll allow only ports for HTTP (80), HTTPS (443), and SSH (22):

sudo apt install ufw -y
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw enable

Check firewall status:

sudo ufw status verbose

Docker can bypass UFW rules, so consider additional protections detailed in this StackOverflow answer.

Step 3: Install Docker Engine and Docker Compose

Docker will manage your containers. To install Docker and Docker Compose, execute these commands:

Install dependencies & Docker GPG key:

sudo apt-get update
sudo apt-get install ca-certificates curl gnupg -y
sudo install -m 0755 -d /etc/apt/keyrings

curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

sudo chmod a+r /etc/apt/keyrings/docker.gpg

Add Docker official repo:

echo \
  "deb [arch=$(dpkg --print-architecture) \
signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo $VERSION_CODENAME) stable" \
| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update

Install Docker and Docker Compose plugin:

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y

Test Docker installation:

sudo docker run hello-world

If successful, move on to Caddy.

Step 4: Installing Caddy Web Server for Automatic HTTPS

Caddy automates HTTPS certificates—perfect for securing your paperless documents.

Run the following to install Caddy:

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl

curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
| sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg

curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
| sudo tee /etc/apt/sources.list.d/caddy-stable.list

sudo apt update
sudo apt install caddy -y

Now configure the reverse proxy in your Caddyfile:

sudo nano /etc/caddy/Caddyfile

Replace yourdomain.com with your domain:

Caddyfile
yourdomain.com {
    reverse_proxy localhost:8000
}

If no domain yet, use port 80 temporarily:

Caddyfile
:80 {
    reverse_proxy localhost:8000
}

Restart caddy to load the changes:

sudo systemctl restart caddy

Step 5: Running paperless-ngx with PostgreSQL Using Docker Compose

Create a working folder and Docker compose configuration for paperless-ngx:

mkdir ~/paperless-ngx
cd ~/paperless-ngx

Create a file named compose.yml with the following content:

compose.yml
services:
  broker:
    image: docker.io/library/redis:7
    restart: unless-stopped
    volumes:
      - redisdata:/data
  db:
    image: docker.io/library/postgres:16
    restart: unless-stopped
    volumes:
      - pgdata:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: paperless
      POSTGRES_USER: paperless
      POSTGRES_PASSWORD: paperless
  webserver:
    image: ghcr.io/paperless-ngx/paperless-ngx:latest
    restart: unless-stopped
    depends_on:
      - db
      - broker
    ports:
      - "8000:8000"
    volumes:
      - data:/usr/src/paperless/data
      - media:/usr/src/paperless/media
      - ./export:/usr/src/paperless/export
      - ./consume:/usr/src/paperless/consume
    env_file: compose.env
    environment:
      PAPERLESS_ADMIN_USER: admin
      PAPERLESS_ADMIN_EMAIL: admin@example.com
      PAPERLESS_ADMIN_PASSWORD: adminpassword
      PAPERLESS_REDIS: redis://broker:6379
      PAPERLESS_URL: https://paperless.sliplane.io
      PAPERLESS_SECRET_KEY: your-secure-random-secret

volumes:
  data:
  media:
  redisdata:
  pgdata:
Want the easy version?

Managed Postgres on Sliplane, with backups and metrics included.

I'd suggest picking a secure secret key for your PAPERLESS_SECRET_KEY environment variable. You can generate a secure key using the following command:

openssl rand -base64 32

The same is true for your PAPERLESS_ADMIN_PASSWORD environment variable!

Save and launch paperless-ngx container:

sudo docker compose up -d

Paperless-ngx is now up and running on your server!

Step 6: Accessing Your Paperless Setup

Open your browser and go to your web address https://yourdomain.com. You should see a login page for paperless-ngx ready for your admin user that you defined in the compose.yml file.

paperless-ngx login

After logging in, you can start uploading and organizing your documents:

paperless-ngx dashboard

Security Recommendations

Maintain secure document storage and server integrity:

  • Set up regular backup routines.
  • Secure SSH with strong passwords or SSH keys.
  • Regularly update client software and apply security patches.
  • Consider tools like fail2ban for extra security.

Updating your paperless-ngx Installation

You can easily update your paperless-ngx installation any time by executing:

sudo docker compose pull
sudo docker compose up -d

Docker will fetch the newest images and automatically update your containers.

Cost Comparison with Managed Providers

Self-hosting typically reduces monthly cost compared to managed alternatives:

ProvidervCPURAMDiskMonthly CostNote
Sliplane22 GB50 GB€22.80Flat rate, free egress, SSL included
Fly.io22 GB40 GB~$17.83Disk and bandwidth billed separately
Render12 GB40 GB~$355 GB bandwidth included on Hobby; disk billed separately
Railway22 GB40 GBUp to ~$66Usage-based; Pro required for a 40 GB volume
Click here to see how these numbers were calculated.

Prices checked July 19, 2026. Assuming an always-on instance running 730 hrs/month, Germany/Amsterdam where regional pricing applies, excluding VAT and egress.

  • Sliplane: Base server with 2 vCPU, 2 GB RAM and 20 GB storage = €17.80/month; the 50 GB storage tier adds €5 -> €22.80/month. Unlimited services, free egress and SSL are included.
  • Fly.io: in Amsterdam, shared-cpu-2x with 2 GB RAM = $11.83/month + 40 GB volume × $0.15/GB = $6 -> ~$17.83/month. Egress is billed separately at $0.02/GB in Europe.
  • Render: closest match is Standard ($25, 1 vCPU / 2 GB) plus 40 GB disk × $0.25/GB = $10 -> ~$35/month. A Hobby workspace includes 5 GB bandwidth, then charges $0.15/GB. Stepping up to Pro compute (2 vCPU / 4 GB) costs $85/month plus disk.
  • Railway (Pro plan): at full resource usage: CPU 2 × $20/vCPU/month = $40; RAM 2 × $10/GB/month = $20; volume 40 × $0.15/GB/month = $6 -> up to ~$66/month. Actual CPU and RAM charges depend on usage. A 40 GB volume requires Pro; its $20/month subscription is a minimum commitment that counts toward usage, not an additional charge. Egress is $0.05/GB.

Bandwidth costs can add up fast on usage-based providers. Use our bandwidth cost comparison tool to see what your egress would cost on each platform.

Bandwidth Cost Growth Comparison

Move the slider or play the animation to compare monthly egress costs. Sliplane stays free as traffic grows.

0 GB
Sliplane
Free
Fly.io
$0.00
Railway
$0.00
Render
$0.00

Egress only, excluding compute and storage. Based on public US/European rates checked July 19, 2026. Render includes its first 5 GB per month. Sliplane egress is free, subject to the Fair Use Policy.

Self-hosting gives you complete control, no hidden fees, and budget-friendly infrastructure.

Need a simpler solution? Check out our managed hosting at sliplane.io for hassle-free paperless-ngx deployment.

Welcome to your cloud platform

Sliplane makes it simple to deploy and scale your apps in the cloud. Start with a container or your favorite framework and grow from there. Try it now and get started in minutes!