Setup Reverse Proxy & SSL with Nginx Proxy Manager

Setup Reverse Proxy & SSL with Nginx Proxy Manager

Bitnesia Linux Mar 27, 2026 1072 ID

In many self-hosting setups, a single public IP address often has to handle dozens of services. Managing all these services using plain Nginx means writing and maintaining numerous server blocks, proxy rules, and route maps that are prone to misconfiguration as services grow. The main challenge is not only the complexity of configuration files, but also managing TLS/SSL certificates for each domain, handling automatic renewals, and dealing with port conflicts.

What is Nginx Proxy Manager (NPM)?

Nginx Proxy Manager (NPM) is a container-based application that wraps Nginx with a web User Interface to manage reverse proxies, hosts, SSL/TLS certificates, redirections, and TCP/UDP streams. NPM provides a dashboard that allows users to add or modify proxy hosts, connect hostnames to backends, and request Let's Encrypt certificates without manually editing Nginx configuration files.

Why Choose NPM?

  • Free & Open Source: A free solution with an active community.
  • User Friendly UI: Suitable for users who prefer not to edit configurations manually.
  • Automatic SSL: Direct integration with Let's Encrypt for automatic certificate issuance and renewal.
  • Quick Comparison:
    • Plain Nginx: Flexible but requires manual configuration and is prone to human error.
    • NPM: Focuses on ease of operation and centralized certificate management.

1. Preparation & Installation

Minimum Server Specifications

  • CPU: 1 vCPU
  • RAM: 1 GB (2 GB recommended if running multiple containers)
  • Disk: 10 GB free space
  • Network: Inbound access on ports 80, 443, and 81

Docker Installation

Use the official Docker installation script. Run the following command:

sudo sh -c "curl -fsSL https://get.docker.com/ | sh"

Docker Compose

Create the npm directory:

mkdir npm
cd npm

Create the compose.yml file:

nano compose.yml

Insert the following configuration, make sure to change the password in the environment section:

services:
  npm:
    image: jc21/nginx-proxy-manager:2.14.0
container_name: nginx-proxy-manager restart: unless-stopped ports: - "80:80" - "81:81" - "443:443" environment: DB_MYSQL_HOST: "db" DB_MYSQL_PORT: 3306 DB_MYSQL_USER: "npm" DB_MYSQL_PASSWORD: "npm_password_here" DB_MYSQL_NAME: "npm" volumes: - ./data:/data - ./letsencrypt:/etc/letsencrypt
depends_on: - db db:
image: 'jc21/mariadb-aria:latest' container_name: mariadb-nginx-proxy-manager restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: "root_password_here" MYSQL_DATABASE: "npm" MYSQL_USER: "npm" MYSQL_PASSWORD: "npm_password_here" volumes: - ./data/mysql:/var/lib/mysql

networks: default: name: npm_network

Explanation:

  1. Services: npm (Reverse Proxy)
    • Ports:
      • 80:80 & 443:443: Main entry points for HTTP and HTTPS traffic.
      • 81:81: Port to access the NPM Admin Dashboard.
    • Environment: Connects NPM to the MariaDB database using the same credentials as the db service.
    • Volumes:
      • ./data: Stores host configurations and user settings.
      • ./letsencrypt: Stores SSL certificates so they persist even after container restarts.
  2. Services: db (Database)
    • Image (mariadb-aria): A database version optimized for NPM to be lighter and faster.
    • Volumes (./data/mysql): Critical to ensure tables and proxy user data are permanently stored on the host disk.
  3. Networks
    • name: npm_network: Creates a dedicated network. Other containers can join this network and be recognized by NPM simply by their container name.

Running & First Login

Start the containers:

sudo docker compose up -d

Verify the docker compose result:

sudo docker compose ps

Example output:

NAME                          IMAGE                             COMMAND             SERVICE   CREATED          STATUS          PORTS
mariadb-nginx-proxy-manager   jc21/mariadb-aria:latest          "/scripts/run.sh"   db        37 seconds ago   Up 36 seconds   3306/tcp
nginx-proxy-manager           jc21/nginx-proxy-manager:latest   "/init"             npm       37 seconds ago   Up 36 seconds   0.0.0.0:80-81->80-81/tcp, [::]:80-81->80-81/tcp, 0.0.0.0:443->443/tcp, [::]:443->443/tcp

Access the admin panel on port 81 (e.g., http://server-ip:81). Proceed to create an admin account.

2. Usage Scenarios

a. Reverse Proxy for Docker Containers

An application running inside a Docker container is to be accessed via the subdomain docker-app.domain.com through NPM on the same host, with both containers connected to the same network (npm_network) to ensure smooth internal communication.

Topology:

User → Internet → NPM (80/443) → Container (container_name:80)

Run the container to be connected with NPM:

sudo docker run -d --name nginx-app --network npm_network -p 127.0.0.1:8080:80 --restart always nginx:alpine

Steps to Create Proxy:

  1. Hosts → Proxy Hosts. Add Proxy Hosts.
  2. Details:
    • Domain Names = e.g., docker-app.domain.com.
    • Scheme = http.
    • Forward Hostname / IP = nginx-app (since it is on the same network, just use the container name)
    • Forward Port = 80.
  3. SSL:
    • Request a new Certificate
    • Force SSL
    • HTTP/2 Support
    • HSTS Enabled
  4. Then Save.
Nginx Proxy Manager - Add Proxy Host
Nginx Proxy Manager - Add Proxy Host

b. Reverse Proxy for Different Hosts

In this scenario, the application is hosted on a different machine than NPM, so access is done using the application server's IP address rather than a container name.

Topology:

User → Internet → NPM (10.130.0.2) → App (10.130.0.3:8080)

Steps to Create Proxy:

  1. Hosts → Proxy Hosts. Add Proxy Hosts.
  2. Details:
    • Domain Names = e.g., other-app.domain.com.
    • Scheme = http.
    • Forward Hostname / IP = application server IP, e.g., 10.130.0.3.
    • Forward Port = application port, e.g., 8080.
  3. SSL:
    • Request a new Certificate
    • Force SSL
    • HTTP/2 Support
    • HSTS Enabled
  4. Then Save.

3. Custom SSL Certificate

If you prefer not to use SSL from Let's Encrypt, Nginx Proxy Manager supports custom SSL certificates.

Adding an SSL Certificate:

  1. Certificates → Add Certificate → Custom Certificate.
  2. Give the certificate a name and upload the certificate key file, certificate file, and intermediate certificate (optional).
  3. Save.

Changing an SSL Certificate:

  1. Edit Proxy Host → SSL tab.
  2. Under SSL Certificate, select the name of the SSL certificate you have added.
  3. Save.

Conclusion

Nginx Proxy Manager simplifies reverse proxy and SSL management through a GUI, making it ideal for self-hosters who want a quick solution without manually editing configuration files. For highly dynamic infrastructures or large-scale orchestration, other solutions may be more suitable. However, for ease of operation and centralized management, NPM is an excellent choice.

Help me create more! Your donations go directly toward better equipment and research for future tutorials.

Support future guides

Related Posts