Skip to content

Self-host Nginx Proxy Manager

updated Jul 2026prices checked · Jul 2026Install verified on Ubuntu 26.04 · Sep 2026 · how we test
We earn commissions when you shop through the links below. Full disclosure →

Put your self-hosted apps behind clean domains with automatic Let's Encrypt TLS — all from a point-and-click web UI. The fastest way to get HTTPS on a home server without touching a config file.

Key facts

LicenseMIT
StackNode.js, Nginx
Min RAM512 MB
Official imageyes
Measured idle RAM80 MB
Difficulty
Our recommendation

Pick Nginx Proxy Manager when you want HTTPS in front of your apps without touching a config file: proxy hosts, redirections, streams, access lists and Let's Encrypt or custom certificates from a web UI on port 81, all in one MIT-licensed container with SQLite in `/data`. The author's stated goal is that it "had to be so easy that a monkey could do it", and it still is. When your stack is Docker-native and you would rather have TLS follow container labels, Traefik is the other answer.

Follow the Nginx Proxy Manager deploy guide →

What you need

  • Any VPS with at least 512 MB of RAM
  • A domain you control — most self-hosted setups need HTTPS in front of them
  • Under an hour if you've used Docker before
Where to host itaffiliate disclosure
Hetzner Cloudrun it on
From $23.59/mo · 2 vCPU / 4 GB / 80 GB · EU + US
Get Hetzner Cloud (opens in new tab)
Kamaterafree trial
From $4/mo · 1 vCPU / 1 GB / 20 GB · US + EU + Asia
Start free on Kamatera → (opens in new tab)
DigitalOceanalso works on
From $6/mo · 1 vCPU / 1 GB / 25 GB · US + EU + Asia
Deploy on DigitalOcean → (opens in new tab)

Paid link — we earn a commission if you shop through it.

Install with Docker Compose

Save this as compose.yml and run docker compose up -d:

# Nginx Proxy Manager — reverse proxy with a web UI
services:
  npm:
    image: jc21/nginx-proxy-manager:latest
    ports: ["80:80", "443:443", "81:81"]
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
    restart: unless-stopped
# docker compose up -d  →  http://SERVER_IP:81
# first visit shows a setup screen that creates the admin account

What you take on

Nginx Proxy Manager has almost no operational surprises; the few there are come from its defaults and packaging:

non-negotiableThere is no longer a default admin@example.com / changeme login. The setup code (backend/setup.js) creates no user unless INITIAL_ADMIN_EMAIL and INITIAL_ADMIN_PASSWORD are set — its own comment reads "Otherwise, users should be shown the setup wizard in the frontend" — and the advanced-config docs describe those variables as "skipping the UI first user setup screen". Your first visit to port 81 creates the admin.
non-negotiableDocker only: "Do I have to use Docker? Yes, that's how this project is packaged." armv7 was dropped in 2.14 (use the 2.13.7 tag on 32-bit ARM); upgrades are docker compose pull && docker compose up -d, with schema changes applied automatically.
non-negotiableIt owns 80 and 443 on the host, so nothing else can. Nothing but the login protects port 81 — our advice is to keep it off the public firewall or proxy it through NPM itself behind an access list.
non-negotiableAn access list with username and password sends an Authorization header to the proxied app; if that app also uses Authorization (NPM itself does), "one of the two logins will be broken" (FAQ). Use another auth method for such apps.
non-negotiableSQLite is the default store, and any DB_MYSQL_* variable overrides it; hosts without IPv6 log "Address family not supported by protocol" until DISABLE_IPV6: 'true' is set. The 512 MB floor is our estimate; upstream publishes no RAM figure.

Head-to-head

More self-hosted tools

We use analytics cookies (Google Analytics, PostHog) to see which guides are useful. No ad networks, no cross-site tracking. See our privacy policy.