Nginx Proxy Manager (NPM) lets you run several websites and apps on one VPS, each on its own domain with a free Let's Encrypt SSL certificate, all managed from a simple web interface. For example, cloud.example.co.nz can go to Nextcloud, status.example.co.nz to Uptime Kuma and n8n.example.co.nz to n8n, all on the same server.
NPM runs in Docker, so this guide works on every operating system we offer: Ubuntu 22.04, 24.04 and 26.04, Debian 12 and 13, AlmaLinux 8, 9 and 10, and Rocky Linux 9 and 10.
Before you start
- Docker must be installed. If it isn't, follow our guide: Install Docker Engine and Docker Compose on your VPS.
- Nothing else using ports 80 or 443. NPM needs both. If you're following one of our other app guides that includes Caddy, leave the Caddy part out and use NPM instead (see "Using NPM with our other guides" below).
- A domain name you can add DNS records for.
- SSH access as root or as a user with sudo rights. If you're logged in as root, you can leave
sudooff the commands.
Step 1: Create the configuration
sudo mkdir -p /opt/nginx-proxy-manager
cd /opt/nginx-proxy-manager
sudo nano compose.yaml
Paste in the following:
services:
npm:
image: jc21/nginx-proxy-manager:latest
container_name: nginx-proxy-manager
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "81:81"
environment:
TZ: "Pacific/Auckland"
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
networks:
default:
name: proxy
Press Ctrl+O and Enter to save, then Ctrl+X to exit. The proxy network at the bottom lets your other Docker apps connect to NPM by name, as explained below.
Step 2: Open the firewall and start NPM
Ubuntu/Debian with UFW enabled:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 81/tcp
AlmaLinux/Rocky with firewalld:
sudo firewall-cmd --permanent --add-service=http --add-service=https --add-port=81/tcp
sudo firewall-cmd --reload
Start NPM:
sudo docker compose up -d
Step 3: Create your admin account
Open http://YOUR_SERVER_IP:81 in your browser straight away. On first run, NPM asks you to create the administrator account. Enter your name, email address and a strong password. Until you do, anyone who finds the page could set it up.
Step 4: Point a domain at your VPS
For each site or app, add an A record in your DNS pointing to your VPS IP address, for example status.example.co.nz. Wait for it to resolve before requesting an SSL certificate.
Step 5: Add a proxy host with free SSL
- In NPM, go to Hosts → Proxy Hosts and click Add Proxy Host.
- Domain Names: enter the domain, for example
status.example.co.nz. - Scheme: usually
http. - Forward Hostname / IP: the container name of your app, for example
uptime-kuma(see the next section). - Forward Port: the port the app listens on inside its container, for example
3001for Uptime Kuma. - Turn on Block Common Exploits, and turn on Websockets Support if the app needs it (many do, including Uptime Kuma, n8n and Vaultwarden).
- On the SSL tab, choose Request a new SSL Certificate, turn on Force SSL and HTTP/2 Support, agree to the Let's Encrypt terms and click Save.
After a few seconds your app is live at https://status.example.co.nz. NPM renews the certificate automatically.
Connecting your other Docker apps
The easiest way for NPM to reach an app is to put the app on the same proxy network and use its container name. Add this to the bottom of the app's compose.yaml:
networks:
default:
name: proxy
external: true
Then remove the app's ports: section, so it's only reachable through NPM, and restart it with sudo docker compose up -d. In NPM, use the app's container name as the Forward Hostname.
For an app that isn't in Docker, or runs on the server directly, use the forward hostname 172.17.0.1, which is how containers reach the host, with the port the app listens on.
Using NPM with our other guides
Our guides for Uptime Kuma and n8n use Caddy for SSL. If you'd rather host them behind NPM:
- Leave out the
caddyservice and the Caddyfile. - Add the
proxynetwork shown above. - Create a proxy host in NPM pointing to
uptime-kumaon port3001, orn8non port5678.
Nextcloud All-in-One runs its own web server and needs a special reverse proxy setup. Follow the Nextcloud AIO reverse proxy guide if you want to run it behind NPM.
Secure the admin panel
Once you're set up, put the NPM admin panel itself behind SSL and stop exposing port 81:
- Add a proxy host such as
npm.example.co.nz, forwarding tonginx-proxy-manageron port81, with an SSL certificate. - Check you can log in at
https://npm.example.co.nz. - In
compose.yaml, change"81:81"to"127.0.0.1:81:81", then runsudo docker compose up -d. Remove the port 81 firewall rule too.
You can also add an Access List in NPM to password-protect or IP-restrict any site.
Keeping it up to date
cd /opt/nginx-proxy-manager
sudo docker compose pull
sudo docker compose up -d
Your settings and certificates are kept in the data and letsencrypt folders in /opt/nginx-proxy-manager. Back these up regularly.
Troubleshooting
- SSL certificate request fails: check that the domain's A record points to this VPS and that port 80 is open. Let's Encrypt checks the domain over port 80.
- 502 Bad Gateway: NPM can't reach the app. Check the container name and port, and that the app is on the
proxynetwork (sudo docker network inspect proxy). - NPM won't start because a port is in use: another web server, such as Nginx, Apache or Caddy, is using port 80 or 443. Stop it first.
Need help?
Our Cloud VPS plans are self-managed, so you're responsible for installing, securing and maintaining the software on your server. If something on our side isn't working, such as the network, or your VPS won't boot, open a support ticket. New to your VPS? Start with our Cloud VPS Getting Started Guide.







