Originally published on byte-guard.net.
TL;DR: Nginx Proxy Manager (NPM) is a free, open-source web GUI for Nginx that gives every self-hosted app a clean domain and an auto-renewing Let's Encrypt certificate without touching a config file. Run it as one Docker container, open ports 80 and 443, point your DNS at the server, and you can have your first HTTPS proxy host live in under five minutes.
The moment you self-host more than one thing ā Vaultwarden, a dashboard, a photo server ā you hit the same wall: everything wants port 443, you're juggling certificates by hand, and exposing raw IP:port to the internet is both ugly and unsafe. Nginx Proxy Manager solves all three. It puts a friendly web UI on top of Nginx and Let's Encrypt, so you map vault.yourdomain.com to an internal container in a few clicks and get a valid TLS certificate that renews itself.
I run NPM in front of every public service on byte-guard.net, and on my Hetzner box the whole stack idles at about 95 MB of RAM. By the end of this guide you'll have it running in Docker, your first app behind HTTPS, and the admin panel locked down the way it should be. Tested on Ubuntu 24.04 LTS with Docker Engine 27.x and the jc21/nginx-proxy-manager v2.12 image on 23 June 2026.
Prerequisites
Before you start, you'll need:
- A VPS or home server with a public IP (a small one is plenty ā see my VPS comparison for what I'd pick today).
- Docker and Docker Compose installed.
- A domain name with an
Arecord pointing at your server's IP (and a wildcard or per-app subdomain record for each service). - Ports 80 and 443 open on the server firewall.
- A hardened base server ā if this is a fresh box, run through hardening your Linux VPS and SSH hardening first.
What Is Nginx Proxy Manager and Why Use It?
Nginx Proxy Manager is a Dockerized reverse proxy that wraps the Nginx engine in a point-and-click dashboard with built-in Let's Encrypt automation. Instead of hand-writing server blocks and running certbot, you fill in a form: domain in, forward host and port out, tick "request a new SSL certificate," done.
It's genuinely free and open source ā there's no paid tier, and your only cost is the server it runs on. The trade-off versus a config-driven proxy is flexibility: if you want infrastructure-as-code or label-based routing, you'll prefer Traefik or Caddy. I break down exactly when to pick each one in Nginx Proxy Manager vs Traefik vs Caddy. For most self-hosters who want a GUI and zero config files, NPM is the fastest path to clean HTTPS.
How Do You Install Nginx Proxy Manager with Docker?
You install Nginx Proxy Manager by running a single Docker Compose service with two persistent volumes. Create a project folder and a docker-compose.yml:
mkdir -p /opt/npm && cd /opt/npm
# /opt/npm/docker-compose.yml
services:
nginx-proxy-manager:
image: jc21/nginx-proxy-manager:latest
container_name: npm
restart: unless-stopped
ports:
- "80:80" # HTTP ā needed for sites + Let's Encrypt HTTP-01 challenge
- "443:443" # HTTPS
- "81:81" # Admin UI (we lock this down in the Security section)
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
Recent NPM versions ship with an embedded SQLite database, so you don't need a separate MariaDB container the way older tutorials show ā fewer moving parts, less RAM. The two volumes are the only state that matters: ./data holds your hosts, users, and the SQLite file; ./letsencrypt holds your certificates. Back up those two folders and you've backed up everything.
Bring it up:
docker compose up -d
docker compose logs -f
The first start takes 20ā30 seconds while it initialises the database. When the logs settle, the container is ready.
Note: If you're on an older install with a
version:line at the top of the Compose file, drop it ā the Compose spec ignores it now and newer Docker prints a warning.
How Do You Log In and Add Your First Proxy Host?
You log in at http://<YOUR_SERVER_IP>:81 with the default credentials, then create a Proxy Host pointing at your app. Open that URL in a browser and sign in with:
-
Email:
admin@example.com -
Password:
changeme
NPM immediately forces you to set a real email and a strong password ā do it now, because this panel controls every certificate and route on the box.
To expose your first app, go to Hosts ā Proxy Hosts ā Add Proxy Host:
-
Domain Names:
vault.yourdomain.com(the subdomain whose DNS already points at this server). -
Scheme:
http, Forward Hostname / IP: the container name or internal IP, Forward Port: the app's internal port (for examplevaultwardenand80). - Tick Block Common Exploits and, for apps that need it, Websockets Support.
- Switch to the SSL tab ā Request a new SSL Certificate ā enable Force SSL, HTTP/2 Support, and HSTS. Agree to the Let's Encrypt terms and save.
A few seconds later NPM provisions the certificate and your app is live over HTTPS. For this to work, NPM has to reach the app ā the cleanest way is to put both containers on the same Docker network and forward by container name:
docker network create proxy
docker network connect proxy npm
# add `networks: [proxy]` to each app's compose service, then reference it by name
That's the whole loop: add a DNS record, add a Proxy Host, get a certificate. Repeat for Vaultwarden, n8n, Nextcloud, or anything else you run.
How Do You Secure Nginx Proxy Manager?
You secure Nginx Proxy Manager by keeping its admin panel off the public internet, using strong credentials, and patching it regularly. The proxy ports (80/443) belong to the world; the admin port (81) does not.
Lock down port 81. This is the single most important step. Either firewall it to your home IP, or rebind it to localhost and reach it over a VPN. Rebinding is the safer default:
ports:
- "80:80"
- "443:443"
- "127.0.0.1:81:81" # admin UI no longer reachable from the internet
After docker compose up -d, reach the panel through an SSH tunnel (ssh -L 8181:localhost:81 user@server) or, better, over your own WireGuard VPN so the dashboard never touches the public internet at all.
The rest of the checklist:
- Use a long, unique admin password (a password manager makes this painless).
-
Patch on a schedule ā
docker compose pull && docker compose up -dpulls the latest image; NPM ships security fixes regularly. - Add an Access List (Hosts ā Access Lists) with HTTP Basic Auth or IP allow-listing in front of admin-only services.
- Run a host firewall so only 80, 443, and SSH are open ā see hardening your Linux VPS.
Note: NPM has no built-in two-factor auth, which is exactly why port 81 should never be publicly reachable. Treat network isolation as your second factor.
Troubleshooting Common Nginx Proxy Manager Problems
Most NPM issues come down to networking or DNS. Here are the ones I hit most often.
Can't reach the admin UI on port 81. The port isn't published, a firewall is blocking it, or you're using https:// ā the admin panel is plain http on 81. Confirm with docker compose ps that the port is mapped, and check your firewall rules.
SSL certificate won't issue. Let's Encrypt's HTTP-01 challenge needs port 80 reachable from the internet and DNS that has actually propagated. If you're behind Cloudflare's orange-cloud proxy, the challenge fails ā grey-cloud the record during issuance or switch to a DNS-challenge certificate.
502 Bad Gateway. NPM can't reach your app. The forward hostname or port is wrong, or the two containers aren't on the same Docker network. Use the container name (not localhost) as the forward host and put both on a shared network.
WebSocket apps (like code editors or chat) won't connect. Edit the Proxy Host and enable Websockets Support.
Lost the admin password. NPM re-creates the default admin@example.com / changeme account if the users table is empty. Back up ./data/database.sqlite, remove your user row with the sqlite3 CLI, restart the container, and log in with the defaults ā then set a new password right away.
Nginx Proxy Manager FAQ
Is Nginx Proxy Manager free?
Yes. Nginx Proxy Manager is free and open source ā there is no paid tier or license fee. Your only cost is the server you run it on, and a small VPS is plenty.
What ports does Nginx Proxy Manager use?
The admin dashboard runs on port 81, while the proxy itself listens on 80 (HTTP) and 443 (HTTPS). Expose 80 and 443 to the internet for Let's Encrypt and your sites, but keep port 81 restricted to your LAN or VPN.
What is the default Nginx Proxy Manager login?
The default credentials are email admin@example.com and password changeme. NPM forces you to set a real email and a strong password the first time you sign in.
Can I run Nginx Proxy Manager on Proxmox?
Yes. Run it as a Docker container inside a VM or LXC on Proxmox ā the same Compose file above works unchanged. Many homelabbers use the Proxmox community helper scripts to spin it up in minutes.
Is Nginx Proxy Manager secure to expose to the internet?
The proxy ports (80/443) are designed to face the internet; the admin panel on port 81 is not. As long as you rebind or firewall port 81, keep the image patched, and use a strong password, NPM is safe to run as your public front door.
Conclusion
Nginx Proxy Manager turns the fiddly parts of self-hosting ā TLS certificates, renewals, and clean domains ā into a form you fill out once per app. You've now got it running in Docker, your first service behind auto-renewing HTTPS, and the admin panel isolated from the public internet. From here, point a few more subdomains at it and put the rest of your stack behind it.
If you're still choosing a proxy, read Nginx Proxy Manager vs Traefik vs Caddy before you commit. And if you'd rather not wire all this up yourself, I'll set up your VPS and reverse proxy for you ā Vaultwarden, n8n, or Nextcloud behind NPM, done for you.
Affiliate disclosure
This post links to a VPS comparison that contains affiliate links. I only recommend providers I actually run production workloads on, and it costs you nothing extra.
ā enim

