Logo

Install Nginx Proxy Manager on Debian

Install Nginx Proxy Manager on Debian

Nginx Proxy Manager is a web interface that drives Nginx in the background. Instead of manually editing `server { }` files, you add your domains in a few clicks and NPM automatically generates the configuration and Let's Encrypt certificates. Perfect for hosting multiple services on the same VPS: Plex, Nextcloud, Vaultwarden, Uptime Kuma, WordPress sites, etc.

Prerequisites

  • Debian 11/12 or Ubuntu 22.04+ VPS with root access
  • Docker and Docker Compose installed (see the Docker guide)
  • Ports 80, 81 and 443 open
  • A domain name pointing to your VPS IP

Step 1: Prepare the environment

Create a folder for NPM:

sudo mkdir -p /opt/nginx-proxy-manager
cd /opt/nginx-proxy-manager

Step 2: docker-compose file

Create the docker-compose.yml file:

sudo nano docker-compose.yml

Paste the following:

services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    container_name: nginx-proxy-manager
    restart: unless-stopped
    ports:
      - '80:80'
      - '81:81'
      - '443:443'
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
    environment:
      DISABLE_IPV6: 'false'

Step 3: Start the container

sudo docker compose up -d

Check the container is running:

sudo docker ps

Step 4: First login

Open your browser at:

http://YOUR_VPS_IP:81

Default credentials:

Important: change the email and password immediately on first login.

Step 5: Add a Proxy Host

Click Hosts → Proxy Hosts → Add Proxy Host.

Fill in:

  • Domain Names: app.your-domain.com
  • Scheme: http
  • Forward Hostname / IP: the internal IP or hostname of the service (e.g. 172.17.0.1 for the host, or another Docker container name)
  • Forward Port: the service port (e.g. 3000)
  • Check Block Common Exploits
  • Check Websockets Support if the service uses WebSocket

Step 6: Enable Let's Encrypt SSL

In the SSL tab of the same proxy host:

  • SSL Certificate: Request a new SSL Certificate
  • Check Force SSL
  • Check HTTP/2 Support
  • Check HSTS Enabled
  • Enter your email for Let's Encrypt
  • Accept the terms

Click Save. NPM contacts Let's Encrypt, validates the domain and installs the certificate automatically.

Step 7: Secure access to the NPM interface

Port 81 exposes the admin interface. Block public access via UFW:

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow from YOUR_FIXED_IP to any port 81
sudo ufw enable

Step 8: Configure a Stream (TCP/UDP)

To proxy a non-HTTP service (Minecraft, remote database, etc.):

Hosts → Streams → Add Stream

  • Incoming Port: public port (e.g. 25565 for Minecraft)
  • Forward Host: target server IP
  • Forward Port: service port
  • TCP / UDP depending on the protocol

Troubleshooting

"502 Bad Gateway"

The service behind the proxy is unreachable. Check:

sudo docker exec -it nginx-proxy-manager ping SERVICE_IP

On Docker, use the container name or host.docker.internal rather than a fixed IP.

Let's Encrypt certificate generation fails

Verify port 80 is open and your domain points to the VPS IP:

dig +short your-domain.com

Cloudflare must be in DNS only mode (grey cloud) during certificate generation, not proxy mode.

Container crashes

Inspect the logs:

sudo docker logs nginx-proxy-manager --tail 100

Useful commands

# Real-time logs
sudo docker logs -f nginx-proxy-manager

# Restart NPM
sudo docker compose restart

# Update NPM
sudo docker compose pull && sudo docker compose up -d

# Backup config
sudo tar -czf npm-backup-$(date +%F).tar.gz data letsencrypt

Conclusion

Nginx Proxy Manager dramatically simplifies the management of a multi-domain reverse proxy. Combined with Docker, you can now host as many services as your VPS can handle, each with its own SSL certificate and subdomain.

Resources

Join our Discord community server

For any questions, suggestions, or just to chat with the community, join us on Discord!

900+Members