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 sudo off 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

  1. In NPM, go to Hosts → Proxy Hosts and click Add Proxy Host.
  2. Domain Names: enter the domain, for example status.example.co.nz.
  3. Scheme: usually http.
  4. Forward Hostname / IP: the container name of your app, for example uptime-kuma (see the next section).
  5. Forward Port: the port the app listens on inside its container, for example 3001 for Uptime Kuma.
  6. Turn on Block Common Exploits, and turn on Websockets Support if the app needs it (many do, including Uptime Kuma, n8n and Vaultwarden).
  7. 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 caddy service and the Caddyfile.
  • Add the proxy network shown above.
  • Create a proxy host in NPM pointing to uptime-kuma on port 3001, or n8n on port 5678.

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:

  1. Add a proxy host such as npm.example.co.nz, forwarding to nginx-proxy-manager on port 81, with an SSL certificate.
  2. Check you can log in at https://npm.example.co.nz.
  3. In compose.yaml, change "81:81" to "127.0.0.1:81:81", then run sudo 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 proxy network (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.

Was this answer helpful? 0 Users Found This Useful (0 Votes)