Skip to main content

Nginx Proxy Manager

Nginx Proxy Manager is a free, open-source proxy manager. It provides a simple and fast interface for configuring and managing proxy hosts, including integrated Letsencrypt. This means that in most cases you don't have to touch config files manually, nor do you have to worry about the SSL certificate.

The project is built as a Docker container, only one database is needed.

Preparation​

Docker network​

First, a Docker network should be created. This means that it is then no longer necessary to release ports for each individual service. Sufficient are then ports 80 and 443 for the proxy manager and possibly others in certain cases.

caution

On some devices (especially on ready NAS devices) it is not possible to release port 80 and 443 because these ports are already used by another service. At this point you can first create a Macvlan network on which ports 80 and 443 can be released.

sudo docker network create proxy-network

Create directory​

mkdir nginx-proxy-manager
cd nginx-proxy-manager
mkdir certs data db
touch .env docker-compose.yml
info

If you are not in the home directory, you may need to add sudo to the commands.

Environment variables​

Some environment variables are needed to configure the proxy manager.

bash -c 'echo "DB_USER=npm" >> .env'
bash -c 'echo "DB_NAME=npm" >> .env'
bash -c 'echo "DB_PWD=$(openssl rand -base64 32)" >> .env'
bash -c 'echo "DB_ROOT_PWD=$(openssl rand -base64 32)" >> .env'

Installation​

The installation is done via Docker Compose.

.../nginx-proxy-manager/docker-compose.yml
version: "3.7"

networks:
proxy-network:
name: proxy-network
internal:
external: false

services:
npm-app:
image: "jc21/nginx-proxy-manager"
container_name: npm-app
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "81:81"
environment:
DB_MYSQL_HOST: "npm-db"
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: $DB_USER
DB_MYSQL_NAME: $DB_NAME
DB_MYSQL_PASSWORD: $DB_PWD
DISABLE_IPV6: "true
networks:
- proxy-network
- internal
volumes:
- ./data:/data
- ./certs:/etc/letsencrypt

npm-db:
image: "jc21/mariadb-aria"
# image: "yobasystems/alpine-mariadb:10.4.17-arm32v7"
container_name: npm-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: $DB_ROOT_PWD
MYSQL_DATABASE: $DB_NAME
MYSQL_USER: $DB_USER
MYSQL_PASSWORD: $DB_PWD
networks:
- internal
volumes:
- ./db:/var/lib/mysql
caution

Bei einem ARM GerΓ€t (z. B. Raspberry Pi) muss ein anderes Image fΓΌr die Datenbank verwendet werden. yobasystems/alpine-mariadb:10.4.17-arm32v7 ist beispielsweise ein geeignetes Image.

sudo docker compose up -d
info

Bei Docker Compose Version 1 lautet der Befehl docker-compose up -d

Proxy-Host​

The GUI should be available under the ip-address of the server and port 81.

Username: admin@example.com
Password: changeme
warning

You should change the credentials after login.

If you have a domain routed to the server, you can create the first proxy host. You can buy an external domain on Netcup from € 5 a year. A .com-Domain costs nearly € 14 a year.(affiliate link)

Now you should be able to access the Nginx Proxy Manager dashboard under the domain you entered.

info

If you are on the network with a router upstream, you need to port share port 80 and 443 to the server.

Access List​

Maybe you should not allow worldwide access for some services. For this purpose there is the Access List function.

With the access list as shown on the image only access from private network is allowed.

10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
tip

If you enter any username or password under "Authorization" in the access list, you have to enter this data as well. If you choose "Satisfy any" it is enough to access from a given IP address or to know the username/password combination.

caution

It is necessary to make sure that the DNS server forwards the domain internally to the server, otherwise the requests will come from an external IP and the access will be blocked again.

tip

If you have locked yourself out by mistake, the proxy hosts are located in the folder data. There you can delete the access restrictions in the respective proxy host.

SSL​

After creating a proxy host, you can also request a Letsencrypt certificate for it via the interface.

info

The proxy host itself does not need to be changed from http:// to https://. The internal forwarding is done via http://. This is for example no longer mandatory if you switch several reverse proxy managers in a row.

Port publish​

If the proxy host provides a connection to the Nginx proxy manager, the port publishing of port 81 is no longer needed, the docker-compose.yml can be adjusted.

.../nginx-proxy-manager/docker-compose.yml
version: "3.7"

networks:
proxy-network:
name: proxy-network
internal:
external: false

services:
npm-app:
image: "jc21/nginx-proxy-manager"
container_name: npm-app
restart: unless-stopped
ports:
- "80:80"
- "443:443"
# - "81:81"
environment:
DB_MYSQL_HOST: "npm-db"
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: $DB_USER
DB_MYSQL_NAME: $DB_NAME
DB_MYSQL_PASSWORD: $DB_PWD
DISABLE_IPV6: "true
networks:
- proxy-network
- internal
volumes:
- ./data:/data
- ./certs:/etc/letsencrypt

npm-db:
image: "jc21/mariadb-aria"
# image: "yobasystems/alpine-mariadb:10.4.17-arm32v7"
container_name: npm-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: $DB_ROOT_PWD
MYSQL_DATABASE: $DB_NAME
MYSQL_USER: $DB_USER
MYSQL_PASSWORD: $DB_PWD
networks:
- internal
volumes:
- ./db:/var/lib/mysql
sudo docker compose down && sudo docker compose up -d

Beispieldienst​

You can connect another host with a proxy host. In this example we will set up a web server.

mkdir homepage
cd homepage
mkdir html
touch html/index.html
touch docker-compose.yml
.../homepage/html/index.html
<!DOCTYPE html>
<html>
<head>
<title>Homepage</title>
</head>
<body>
<h1>Homepage</h1>
<p>This is a homepage.</p>
</body>
</html>
.../homepage/docker-compose.yml
version: "3.7"

networks:
proxy-network:
external:
name: proxy-network

### SERVICE ###
services:
homepage:
container_name: homepage
image: nginx:latest
restart: unless-stopped
networks:
- proxy-network
security_opt:
- no-new-privileges:true
volumes:
- /html:/usr/share/nginx/html:ro
sudo docker compose up -d

Now you have to configure a new proxy host in Nginx Proxy Manager with the hostname homepage and port 80.

You can enter the new site under homepage.domain.de.

Update​

Thanks to Docker and Docker Compose, updating is easy.

sudo docker compose pull
sudo docker compose down
sudo docker compose up -d