VPS Guide · Self-Hosting
Nginx Proxy Manager: Complete Installation and Setup Guide 2026
If you run a VPS with multiple services — a blog, a Nextcloud instance, a Git server, or a home dashboard — you've likely faced the challenge of routing multiple subdomains to different internal ports. Nginx Proxy Manager (NPM) solves this elegantly: a Docker-based reverse proxy with a polished web UI and automatic free SSL from Let's Encrypt.
This guide covers everything from installation on a fresh VPS to advanced features like Access Lists, HTTP Authentication, and Docker network configuration. All facts sourced from the official NPM documentation at nginxproxymanager.com (version 2.16.0, October 2026).
Table of Contents
- What Is Nginx Proxy Manager?
- Key Features and Benefits
- System Requirements
- Step 1 — Install Docker
- Step 2 — Install NPM with Docker Compose
- Step 3 — First Login and Setup
- Step 4 — Create Your First Proxy Host
- Step 5 — Configure SSL Certificate
- Setting Up Redirections
- Access Lists and HTTP Auth
- Docker Network Best Practices
- Troubleshooting Common Issues
- Frequently Asked Questions
What Is Nginx Proxy Manager?
Nginx Proxy Manager (NPM) is an open source Docker image created by Jamie Curnow (GitHub: jc21). It provides a clean web interface for managing Nginx reverse proxies, removing the need to write and maintain Nginx configuration files manually.
A reverse proxy sits in front of your backend services and routes incoming HTTP/HTTPS requests to the appropriate service based on the hostname. NPM handles all the complexity — SSL termination, certificate renewal, header forwarding, and WebSocket proxying — through a few clicks in its admin dashboard.
Key Features and Benefits
- Beautiful Admin UI — built on Tabler; clean and intuitive for non-Nginx users
- Free SSL via Let's Encrypt — one-click certificate issuance and automatic renewal
- Proxy Hosts — forward a domain to any internal IP:Port
- Redirection Hosts — 301/302 redirects between domains
- Streams — TCP/UDP port forwarding for non-HTTP protocols
- 404 Hosts — return 404 for domains you don't want to serve
- Access Lists — IP whitelisting and HTTP Basic Authentication
- Multiple Users — user management with granular permissions and audit log
- Custom SSL — upload your own certificates if needed
- Advanced Nginx Config — power users can inject raw Nginx directives
| Feature | NPM | Traefik | Caddy |
|---|---|---|---|
| Web UI | Full-featured | Basic | None (config only) |
| Auto SSL | Yes | Yes | Yes |
| Docker-native | Yes | Yes | Supported |
| Best for | Self-hosters | K8s / Microservices | Config-as-code |
| Learning curve | Low | Medium-High | Medium |
| Database | SQLite / MySQL | None (config file) | None (config file) |
Data as of October 2026 — verify current features at each project's official site
System Requirements
Before installing NPM, ensure your VPS meets these requirements:
- OS: Ubuntu 20.04+, Debian 11+, Rocky Linux 8+, or similar
- RAM: 512 MB minimum (1 GB+ recommended for multiple services)
- Disk: 10 GB minimum
- Open ports: 80, 81, and 443 must be accessible
- Domain: A DNS A record pointing to your VPS IP
- Docker + Docker Compose: installed (see next step)
Step 1 — Install Docker on Ubuntu
SSH into your VPS and run the following commands (tested on Ubuntu 22.04 and 24.04):
# Update package list and upgrade
sudo apt update && sudo apt upgrade -y
# Install prerequisites
sudo apt install -y ca-certificates curl gnupg
# Add Docker's GPG key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# Add Docker repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker Engine and Compose plugin
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Add your user to the docker group
sudo usermod -aG docker $USER
newgrp docker
Verify the installation:
docker --version
docker compose version
Step 2 — Install Nginx Proxy Manager with Docker Compose
Create a directory for NPM and a docker-compose.yml file:
mkdir ~/nginx-proxy-manager && cd ~/nginx-proxy-manager
nano docker-compose.yml
Paste the following configuration:
services:
app:
image: 'docker.io/jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
- '80:80' # HTTP traffic
- '81:81' # Admin UI
- '443:443' # HTTPS traffic
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
Save the file and start NPM:
docker compose up -d
Verify that the container is running:
docker compose ps
You should see the container in a Up state with ports 80, 81, and 443 bound.
sudo ufw allow 80,81,443/tcp && sudo ufw reload
Step 3 — First Login and Initial Setup
Open your browser and navigate to http://<your-vps-ip>:81 (e.g., http://123.45.67.89:81)
Log in with the default credentials:
- Email:
[email protected] - Password:
changeme
NPM will immediately prompt you to change your email address and password. Do this now — never leave default credentials in a production environment.
Dashboard Overview
After login, the main dashboard displays counters for:
- Proxy Hosts — your configured reverse proxies
- Redirection Hosts — domain redirects
- Streams — TCP/UDP forwarding rules
- Dead Hosts — domains returning 404
Step 4 — Create Your First Proxy Host
Suppose you have a service running on localhost:3000 (for example, Gitea, Vaultwarden, or a Node.js app) and want to expose it at app.example.com.
- Go to Hosts → Proxy Hosts
- Click "Add Proxy Host"
- Fill in the Details tab:
- Domain Names:
app.example.com - Scheme:
http - Forward Hostname/IP:
localhost(or container name if using Docker networks) - Forward Port:
3000 - Enable "Block Common Exploits"
- Enable "Websockets Support" if your app uses WebSockets
- Domain Names:
- Click "Save"
NPM will immediately generate the Nginx configuration and apply it. Your service should now be accessible at http://app.example.com.
Step 5 — Configure Free SSL from Let's Encrypt
To secure your proxy host with HTTPS:
- Edit your Proxy Host → click the "SSL" tab
- Under SSL Certificate, select "Request a new SSL Certificate"
- Enable "Force SSL" — this redirects all HTTP traffic to HTTPS
- Enable "HTTP/2 Support"
- Enter your Email Address for Let's Encrypt notifications
- Agree to the Let's Encrypt Terms of Service
- Click "Save"
NPM will contact Let's Encrypt via HTTP-01 challenge, obtain a certificate valid for 90 days, and automatically renew it before expiry.
Wildcard SSL with DNS Challenge
For wildcard certificates (*.example.com), you need DNS Challenge instead of HTTP-01. In the SSL tab, select "Use a DNS Challenge" and choose your DNS provider (Cloudflare, Route53, etc.) with the appropriate API credentials.
Setting Up Redirection Hosts
Use Redirection Hosts to forward one domain to another — for example, www.example.com → example.com:
- Go to Hosts → Redirection Hosts
- Click "Add Redirection Host"
- Domain Names:
www.example.com - Forward Domain Name:
example.com - HTTP Code: 301 (permanent) or 302 (temporary)
- Enable SSL if desired, then "Save"
Access Lists and HTTP Basic Authentication
Access Lists restrict who can reach a Proxy Host — by IP address or with a username and password prompt.
Creating an Access List
- Go to Access Lists → Add Access List
- Give it a descriptive name (e.g., "Admin Only")
- In the Authorization tab: add username/password pairs for HTTP Basic Auth
- In the Access tab: add IP addresses to allow or deny
- Save, then assign this Access List to any Proxy Host via the Details tab
Who Is NPM Best For?
NPM is the ideal choice for self-hosters and homelab enthusiasts who want to run multiple services on a single VPS with clean domain routing and automatic SSL — without touching a single Nginx configuration file.
Docker Network Best Practices
When multiple services run in Docker containers, using a shared network lets NPM communicate with them by container name rather than localhost.
Create a shared network:
docker network create proxy_net
Update NPM's docker-compose.yml:
services:
app:
image: 'docker.io/jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
- '80:80'
- '81:81'
- '443:443'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
networks:
- proxy_net
networks:
proxy_net:
external: true
For each backend service's docker-compose.yml, add the same network:
networks:
- proxy_net
networks:
proxy_net:
external: true
Then in NPM's Proxy Host configuration, use the container's service name as the Forward Hostname instead of localhost.
Troubleshooting Common Issues
SSL Certificate Request Fails
- Verify the domain resolves to your VPS IP:
dig +short app.example.com - Confirm port 80 is open from the internet (Let's Encrypt requires it for HTTP-01 challenge)
- Check NPM logs:
docker compose logs app | grep -i error - Wait for DNS propagation — changes can take up to 48 hours, though usually under 30 minutes
502 Bad Gateway
- Confirm the backend service is running:
curl http://localhost:3000 - If using Docker networks, verify both containers are in the same network:
docker network inspect proxy_net - Check that the forward port number is correct
Admin UI on Port 81 Unreachable
- Check the container is running:
docker compose ps - Ensure port 81 is allowed:
sudo ufw allow 81/tcp - View logs:
docker compose logs app
Updating NPM to the Latest Version
docker compose pull
docker compose up -d
Related Guides
Need a VPS to Run NPM?
We recommend VPS providers with servers in Asia for low latency and reliable uptime.
See AsiaGB VPS See Bangmod CloudFrequently Asked Questions
Is Nginx Proxy Manager free?
Yes. NPM is open source under the MIT License. It is completely free for both personal and commercial use. The Docker image is available on Docker Hub as jc21/nginx-proxy-manager.
Can NPM issue wildcard SSL certificates?
Yes, but it requires DNS Challenge instead of the default HTTP-01 challenge. You need to select your DNS provider (Cloudflare, Route53, etc.) and provide API credentials in the SSL tab.
What database does NPM use?
By default, NPM uses an embedded SQLite database stored in the ./data volume. For larger deployments, it also supports MySQL/MariaDB — though SQLite is sufficient for most self-hosting use cases.
Does NPM support armv7 (Raspberry Pi)?
NPM 2.14+ dropped armv7 support because Node.js dropped armhf. If you're on an older Raspberry Pi, use image tag 2.13.7 explicitly in your docker-compose.yml.
Should I expose port 81 (Admin UI) to the internet?
No. Best practice is to close port 81 from external access (sudo ufw delete allow 81/tcp) and access the Admin UI through an SSH tunnel or VPN. This prevents unauthorized access to your proxy manager.
Can NPM proxy non-HTTP protocols?
Yes, through the Streams feature. Streams allow you to forward TCP and UDP ports, which is useful for databases, game servers, or any non-HTTP service.
Summary
Nginx Proxy Manager (v2.16.0, October 2026) is the go-to reverse proxy solution for self-hosters who want clean domain routing and automatic SSL without the complexity of manual Nginx configuration. Its polished web UI, zero-config Let's Encrypt integration, and active community make it the easiest path to exposing multiple services from a single VPS.
Its main limitation is that it's not designed for config-as-code or Kubernetes environments — for those use cases, Traefik or Nginx Ingress Controller are better choices. But for personal servers, homelabs, and small team infrastructure, NPM is hard to beat.