We all know the manual management of Nginx Proxy hosts, redirections, and SSL can be tedious. The Nginx Proxy Manager project started as Jamie Curnow’s personal project with the intention of providing an easier way to create reverse proxying hosts and terminate SSL using Nginx. The project has optional advanced options for advanced proxying use. Below are some of the good features of Nginx Proxy Manager.
- Support for user management, permissions granting and audit logging
- It ships with a beautiful and secure Admin Interface based on Tableropen in new window
- Support for Free SSL using Let’s Encrypt or an option to provide your own custom SSL certificates
- Ability to create forwarding domains, redirections, streams and 404 hosts without mastery of Nginx concepts
- For super users there is Advanced Nginx configuration available
- Support for access lists and basic HTTP Authentication for specific hosts
- Ease of deployment: It’s built as a Docker Image for quick installation
In the next sections we perform the installation, configurations and demonstrate the basic usage of Nginx Proxy Manager in Docker Container. You don’t need deep Linux skills to follow this article along.
Install Docker Engine
Nginx Proxy Manager is packaged as container image that can be run on Docker, Podman or any similar container engine. For simplicity, we are using Docker Engine in this article. Follow the article below to perform the installation of Docker Container Engine.
After the installation, you can verify the version of Docker.
$ docker version
Client: Docker Engine - Community
Version: 25.0.3
API version: 1.44
Go version: go1.21.6
Git commit: 4debf41
Built: Tue Feb 6 21:13:09 2024
OS/Arch: linux/amd64
Context: default
Server: Docker Engine - Community
Engine:
Version: 25.0.3
API version: 1.44 (minimum version 1.24)
Go version: go1.21.6
Git commit: f417435
Built: Tue Feb 6 21:13:09 2024
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.28
GitCommit: ae07eda36dd25f8a1b98dfbf587313b99c0190bb
runc:
Version: 1.1.12
GitCommit: v1.1.12-0-g51d5e94
docker-init:
Version: 0.19.0
GitCommit: de40ad0
Run Nginx Proxy Manager in Docker Container
Nginx Proxy Manager will use ports 80 for http, port 443 for https traffic, and port 81 for its admin dashboard. If you have another web server such as Nginx, or Apache on the same host, consider disabling it.
To stop current Nginx and Apache web services on Debian and RHEL based system, use the following commands.
### Debian / Ubuntu ###
sudo systemctl disable --now nginx apache2
### RHEL based systems ###
sudo systemctl disable --now nginx httpd
Create directories that will have Nginx proxy manager data.
mkdir ~/nginx-proxy-manager && cd ~/nginx-proxy-manager
Docker compose is a command line tool used to define and run one or multiple container applications from definitions in a single YAML file called docker-compose.yml
. Let’s create this file
vim docker-compose.yml
Here we have the default configurations required to run the application using Compose. The default database is SQLite.
version: '3.8'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
# These ports are in format <host-port>:<container-port>
- '80:80' # Public HTTP Port
- '443:443' # Public HTTPS Port
- '81:81' # Admin Web Port
# Add any other Stream port you want to expose
# - '21:21' # FTP
# Uncomment the next line if you uncomment anything in the section
# environment:
# Uncomment this if you want to change the location of
# the SQLite DB file within the container
# DB_SQLITE_FILE: "/data/database.sqlite"
# Uncomment this if IPv6 is not enabled on your host
# DISABLE_IPV6: 'true'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
If you wish to use MariaDB database, here is an example of what your docker-compose.yml
will look like:
version: '3.8'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
# These ports are in format <host-port>:<container-port>
- '80:80' # Public HTTP Port
- '443:443' # Public HTTPS Port
- '81:81' # Admin Web Port
# Add any other Stream port you want to expose
# - '21:21' # FTP
environment:
# Mysql/Maria connection parameters:
DB_MYSQL_HOST: "db"
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: "npm"
DB_MYSQL_PASSWORD: "npm"
DB_MYSQL_NAME: "npm"
# Uncomment this if IPv6 is not enabled on your host
# DISABLE_IPV6: 'true'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
depends_on:
- db
db:
image: 'jc21/mariadb-aria:latest'
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: 'npm'
MYSQL_DATABASE: 'npm'
MYSQL_USER: 'npm'
MYSQL_PASSWORD: 'npm'
MARIADB_AUTO_UPGRADE: '1'
volumes:
- ./mysql:/var/lib/mysql
Activate the container to run by executing the following commands.
docker compose up -d
Expected command execution output.
[+] Running 2/2
✔ Network nginx-proxy-manager_default Created 0.1s
✔ Container nginx-proxy-manager-app-1 Started 0.2s
If all goes well you will see output like below.

As the apps is started, the following operations will happen.
- GPG keys are generated and saved in the data folder
- The database will initialize with table structures
- A default admin user will be created – with creds [email protected] / changeme
The services ports as stated earlier are 80, 443 and 81.
$ ss -tunelp | egrep '80|443|81'
tcp LISTEN 0 4096 0.0.0.0:80 0.0.0.0:* users:(("docker-proxy",pid=608762,fd=4)) ino:8689062 sk:100d cgroup:/system.slice/docker.service <->
tcp LISTEN 0 4096 0.0.0.0:81 0.0.0.0:* users:(("docker-proxy",pid=608740,fd=4)) ino:8689043 sk:100e cgroup:/system.slice/docker.service <->
tcp LISTEN 0 4096 0.0.0.0:443 0.0.0.0:* users:(("docker-proxy",pid=608718,fd=4)) ino:8688177 sk:100f cgroup:/system.slice/docker.service <->
tcp LISTEN 0 4096 [::]:80 [::]:* users:(("docker-proxy",pid=608768,fd=4)) ino:8689067 sk:1010 cgroup:/system.slice/docker.service v6only:1 <->
tcp LISTEN 0 4096 [::]:81 [::]:* users:(("docker-proxy",pid=608746,fd=4)) ino:8688198 sk:1011 cgroup:/system.slice/docker.service v6only:1 <->
tcp LISTEN 0 4096 [::]:443 [::]:* users:(("docker-proxy",pid=608724,fd=4)) ino:8688181 sk:1012 cgroup:/system.slice/docker.service v6only:1 <->
You can access Nginx Proxy Manager on http://ServerIP_or_FQDN:81

Default login details are;
- Email: [email protected]
- Password: changeme
Edit the user after login and set names and correct email address.

Change its password from change to a stronger password.

The dashboard will have the following sections in the navigation menu.

Using Let’s Encrypt SSL (wildcard)
I find using Let’s Encrypt wildcard SSL for all sub-domains more ideal than generating a certificate for each domain. To create new SSL certificates, navigate to “SSL Certificates” then “Add SSL Certificate”.

For my use case, I’ll go with “Use a DNS Challenge” since my domain is hosted in Cloudflare. Input *.domain for wildcard sub-domain ssl certificate. You can also add primary domain so that the certificate will have both.

Save and wait for the certificate to be generated.

Add Proxy Hosts
For a service that you will need to be exposed, you must create a DNS A record for a domain name pointing to the IP address of Nginx proxy manager. For example;
grafana.computingforgeeks.com in A 192.168.20.3
For the rest parts of this tutorial we will use computingforgeeks.com as the domain, replace it with your actual domain name.
To add a new virtual host, navigate to Hosts > Proxy Hosts.

Click on “Add Proxy Host” to configure a new virtual host.

Complete the form by filling in the following details.
- Domain Names: Input one or more domain names that the service will be accessed on.
- Scheme: Set the scheme used by Nginx to access the service, Thus is not the scheme used for the proxy itself.
- Forward Hostname/IP: Configure the IP address or hostname where the backend service is running. It can be a local or public IP.
- Forward Port: The service port used by the backend service.
- Block Common Exploits: You can toggle this option on.
- Other fields can be left at their defaults.

Under SSL section, you can select to request a new SSL Certificate or use existing added earlier. Fill in the other information required to get Let’s Encrypt SSL certificate.

All Proxy hosts are listed under Proxy Hosts menu section. Hit the source URL to test your nginx proxy service.

Conclusion
In this article, we’ve demonstrated how you can use Nginx Proxy Manager to manage external front or public access to the backend services secured with Let’s Encrypt SSL certificates. This is considered to be a basic usage guide, but more advanced setups can be done. This is to only showcase the functionalities and the effectiveness of nginx proxy manager.