How to Use Nginx Proxy Manager
If you have ever tried to configure an Nginx reverse proxy by hand, you know the pain of editing configuration files, debugging syntax errors, and manually renewing SSL certificates. Nginx Proxy Manager (NPM) eliminates this friction by providing a clean, graphical interface to manage your infrastructure.
In this comprehensive guide for 2025, we will cover everything from initial installation to advanced security integrations like CrowdSec and Tailscale.
---
Why Use Nginx Proxy Manager?
Before diving into the "how," it is essential to understand the "why." The search query "why use an nginx proxy" is common, and the answer lies in abstraction and automation.
The Power of Reverse Proxies
A reverse proxy sits in front of your web servers and forwards client requests (e.g., web browser) to those backend servers. This architecture provides:
1. Load Balancing: Distributing traffic across multiple servers to ensure no single server bears too much load. 2. Security: Hiding the IP address and characteristics of your backend servers. 3. SSL Termination: Offloading the encryption/decryption process from the backend servers to the proxy.
NPM vs. Native Nginx
While standard Nginx is incredibly powerful, it has a steep learning curve. Nginx Proxy Manager builds on top of the Nginx Open Source Restful API (using the underlying OpenResty bundle) but adds:
| Feature | Native Nginx | Nginx Proxy Manager | | :--- | :--- | :--- | | Configuration | Manual text file editing (nginx.conf) | Web-based Dashboard (GUI) | | SSL Management | Manual Certbot command line | One-click Let's Encrypt with auto-renewal | | Access Control | Complex auth_basic blocks | GUI-based Access Lists & SSO support | | WAF Support | Manual compilation of modules | One-click CrowdSec Bouncer integration |
---
Part 1: Installation and Setup
NPM is designed to run as a Docker container. This ensures that the environment is consistent and dependencies are managed automatically.
1. Prerequisites
- A server running a Linux distribution (Ubuntu, Debian, Raspberry Pi OS) or a Synology NAS.
- Docker and Docker Compose installed.
- A domain name (e.g.,
example.com) pointed to your server's public IP address via A Records. For local use, you can edit your hosts file or use a split-horizon DNS.
2. Docker Compose Configuration
Create a file named docker-compose.yml with the following content. This is the standard deployment method for 2025.
version: '3.8'
services: app: image: 'jc21/nginx-proxy-manager:latest' restart: unless-stopped ports: - '80:80' # Public HTTP Port - '443:443' # Public HTTPS Port - '81:81' # Admin Web Port environment: # Uncomment if you want to use MySQL/MariaDB # DB_SQLITE_FILE: "/data/database.sqlite" # Or use a real database for production DB_MYSQL_HOST: "db" DB_MYSQL_USER: "npm" DB_MYSQL_PASSWORD: "npm" DB_MYSQL_NAME: "npm" volumes: - ./data:/data - ./letsencrypt:/etc/letsencrypt db: image: 'jc21/mariadb-aria:latest' restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: 'npm' MYSQL_DATABASE: 'npm' MYSQL_USER: 'npm' MYSQL_PASSWORD: 'npm' volumes: - ./data/mysql:/var/lib/mysql
*Run the container:*
docker-compose up -d
3. Initial Login
Once running, navigate to http://.
admin@example.comchangemeYou will be immediately prompted to change your credentials and provide your full name.
---
Part 2: How to Use Nginx Proxy Manager (The Core)
The primary use case for NPM is taking a service running on a specific port (e.g., a Python Flask app on port 5000) and making it accessible via a clean domain (e.g., app.example.com).
Scenario: Exposing a Web Application
Step 1: Define Proxy Host
1. Navigate to the Hosts > Proxy Hosts tab. 2. Click Add Proxy Host. 3. Fill in the required details: * Domain Names: app.yourdomain.com * Scheme: http * Forward Hostname / IP: 172.17.0.1 (Docker bridge IP) or the LAN IP of the server. * Forward Port: 5000 (The port your app is running on).
Step 2: Enable SSL (HTTPS)
NPM shines here. You don't need to generate certificates manually.
1. In the SSL tab of the Proxy Host configuration: * SSL Certificate: "Request a new SSL Certificate" * Force SSL: Enable this (Redirects HTTP to HTTPS) * HTTP/2 Support: Enable. * HSTS Enabled: Highly recommended for security. 2. Agree to the Let's Encrypt Terms of Service. 3. Save.
Within seconds, NPM will validate your domain, generate the SSL certificate, and configure Nginx to serve your application over HTTPS.
---
Part 3: Advanced Configuration
Beyond simple proxying, NPM allows for granular control over traffic.
Custom Locations (Subfolders)
A common query is "how to nginx proxy manager to a subfolder." If you want example.com/api to point to a different service than example.com/:
1. Edit your Proxy Host. 2. Go to the Custom locations tab (available in newer NPM versions). 3. Click Add Location. * Location: /api * Scheme: http * Forward Hostname: backend-server-ip * Forward Port: 8080
This allows you to route traffic based on URL paths without complex Regex rewriting.
Access Lists
If you want to password protect your admin panel or a specific site:
1. Go to Access Lists > Add Access List. 2. Name: Admin Protection. 3. Authorization: Basic Auth. 4. Create a username and strong password. 5. Apply to Host: Select the domain you wish to protect.
Now, visiting that site prompts for a username and password before the proxy ever forwards the request to the backend.
Custom Nginx Configuration
Sometimes the GUI isn't enough. For example, you might need to adjust the client_max_body_size to allow large file uploads.
1. Go to Proxy Hosts > Edit. 2. Navigate to the Advanced tab. 3. Inject custom Nginx configuration:
client_max_body_size 100M;
proxy_buffering off;
---
Part 4: Security Hardening with CrowdSec
One of the most powerful keywords in the 2025 ecosystem is "crowdsec nginx proxy manager bouncer." CrowdSec is a modern, behavior-based security engine. Integrating it with NPM allows your proxy to automatically ban IPs that attempt SQL injections, path traversals, or brute force attacks.
How to Integrate CrowdSec Bouncer
1. Install CrowdSec: Install CrowdSec on your host machine.
curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash
sudo apt install crowdsec
2. Install the Nginx Bouncer: This is the component that talks to CrowdSec and updates the Nginx blocklist.
# The bouncer needs to be able to modify the config generated by NPM or run in a container sidecar.
# A common method for Docker users is using the bouncer container: docker run -d --name crowdsec-bouncer --network host \n -v /var/run/docker.sock:/var/run/docker.sock \n crowdsecurity/nginx-bouncer:latest \n -c /etc/crowdsec/bouncers/crowdsec-bouncer.yaml
*Note: In a docker-compose setup, ensure the bouncer container has access to the Nginx configuration volume or runs in network_mode: "host" to inspect traffic correctly.*
3. Configuration: Open the NPM Dashboard. Go to the proxy host you want to protect. In the Custom tab, ensure that the bouncer logic is injected or that CrowdSec has detected the Nginx container.
Once active, if a scraper tries to enumerate your WordPress installation, CrowdSec detects the behavior and sends the IP to the Bouncer. NPM immediately returns a 403 Forbidden for that IP.
---
Part 5: Local and VPN Usage (Tailscale)
Many users search for "how to use nginx proxy manager with vpn tailscale."
The Use Case
You have a server at home, but you don't want to open ports 80/443 to the public internet. You want to access your internal dashboard securely while traveling.
The Solution
1. Install Tailscale on the same machine running Nginx Proxy Manager. 2. Log into Tailscale and enable "Funnel" (if you need public exposure) or simply use the MagicDNS for private access. 3. Configure NPM for Tailscale IPs: When setting up a Proxy Host, set the Domain Name to your Tailscale MagicDNS name (e.g., node-name.tailnet-name.ts.net). 4. Certificate Management: Tailscale provides automated certificates for .ts.net domains. However, if you want to use NPM's Let's Encrypt integration, ensure port 80 is reachable. If purely internal, you can generate your own self-signed certs in NPM or use Tailscale's built-in HTTPS proxy.
Alternatively, you can restrict access to the Proxy Host via NPM's Access Control List, allowing *only* the Tailscale subnet (usually 100.x.x.x) or specific IP addresses.
---
Troubleshooting Common Issues
"502 Bad Gateway"
This is the most common error. It means Nginx is up, but it cannot reach your backend service.
1. Check Docker Networking: If your app is in Docker and NPM is in Docker, are they on the same network? By default, Docker containers cannot talk to each other via localhost. 2. Solution: Put both containers in a custom Docker network defined in docker-compose.yml.
networks:
default: name: npm-network
SSL Renewal Failures
If Let's Encrypt fails, it is usually a DNS issue or port 80 being blocked. 1. Ensure Port 80 is open to the world. HTTP-01 validation *must* happen on port 80. 2. Check that your DNS A record actually points to your server IP.
Conclusion
Nginx Proxy Manager bridges the gap between the complex power of Nginx and the usability needs of modern developers. By mastering the Proxy Hosts, SSL management, and integrating security tools like CrowdSec, you can build a production-grade ingress controller for your homelab or startup in minutes, not hours. Whether you are exposing a Python Flask app, a Nextcloud instance, or a local development server via Tailscale, NPM is the essential tool in your 2025 stack.