THE DIGITAL LIFE

THE DIGITAL LIFE

THE DIGITAL LIFE

NGINX Proxy Manager – How-To Installation and Configuration

If you’re searching for a small and easy to set up a reverse proxy with a beautiful UI, you’re at the right place. In this tutorial, I will show you how to install the NGINX proxy manager in a docker container on Linux.


Prerequisites

For this tutorial, you need a Linux server that has docker and docker-compose installed. Docker-Compose is a simple and easy container management system, that is based on static configuration files. But you could also deploy NGINX proxy manager in other container management systems if you want. If you want to know how to install docker on Linux, just have a look at the official docker documentation and docker-compose documentation.


What is NGINX proxy manager

NGINX proxy manager is a reverse proxy management system, that is based on NGINX with a nice and clean web UI. You can also obtain trusted SSL certificates, manage several proxies with individual configs, customizations, and intrusion protection. It is open-source and maintained GitHub. It’s perfect for small environments like home labs or small server environments. You can easily expose any web service or application with it. It includes a free SSL certificate management by letsencrypt that can also be used to obtain wildcard certs. To deploy the NGINX proxy manager you need a small MySQL database container and the NGINX container. Let’s have a look at how to deploy this easily with docker-compose.


Deploy NGINX proxy manager in docker how-to

Now we need to create our docker-compose file. I will create a new project folder in the /opt directory called “nginxproxymanager”. Then I create a docker-compose.yaml file with the following template.

version: '3'
services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    ports:
      - '80:80'
      - '81:81'
      - '443:443'
    environment:
      DB_MYSQL_HOST: "db"
      DB_MYSQL_PORT: 3306
      DB_MYSQL_USER: "npm"
      DB_MYSQL_PASSWORD: "npm"
      DB_MYSQL_NAME: "npm"
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
  db:
    image: 'jc21/mariadb-aria:10.4'
    environment:
      MYSQL_ROOT_PASSWORD: 'npm'
      MYSQL_DATABASE: 'npm'
      MYSQL_USER: 'npm'
      MYSQL_PASSWORD: 'npm'
    volumes:
      - ./data/mysql:/var/lib/mysql

Start the NGINX proxy manager stack with the following command.

docker-compose up -d

Login to the web UI of NGINX proxy manager

Now we can log in to the web UI. Simply use your browser to connect to your server by using the IP address or an FQDN and connect on port “81”. Log in with the username “admin@example.com” and the password “changeme”. Next, you should change your username and password, and that’s it!

You can create proxy hosts, obtain trusted SSL certificates, manage access control lists and much more. First let’s add a new domain on our DNS server, that we’re able to obtain a new SSL certificate.


Create a DNS A record for your domain that points to your server

I create a new A record on my server that is called “research.the-digital-life.com” that points to the public IP of my cloud server. I’m using DigitalOcean as my DNS provider because their DNS management is completely free and very easy. If you want to try out DigitalOcean use this link to get 100$ for 60-days for free!


Obtain trusted SSL certificates for your services

Next, we need to obtain our SSL certs in the NGINX proxy manager UI. Go to “SSL certificates” and enter your details. Note, if you want to use a wildcard cert like “*.the-digital-life.com”, you will need to enable the “Use a DNS Challenge” method. Select your DNS provider and follow the instructions, based on your provider’s documentation. But in this example, I won’t use a DNS challenge, because I want to obtain an SSL cert for the subdomain “research.the-digital-life.com”.

Once you click on “Save”, the NGINX proxy manager tries to obtain your trusted SSL cert. If everything is successful, you should see your cert in the list.


Expose a simple unsecured web application

To expose a simple web application that is running on our server, we will create a new “Proxy Host”. In this example, I will expose a docker container that is running “nextcloud”.

Note, it’s very important to understand how networking works in docker. Because docker networks are isolated from each other, you need to make sure that the app you want to expose is connected to the NGINX proxy manager network “nginxproxymanager_default”. I’m doing this by running the following command. Alternatively, you could also add more services in the docker-compose.yaml file.

docker run --network nginxproxymanager_default --name=nextcloud nextcloud

Create a new proxy host

Now we can create a new “Proxy Host”. Make sure you select the “Scheme” “HTTP” if you want to expose any unsecured application that doesn’t use HTTPS. This is the protocol of the destination. Fill in the “domain names”, which should match all domains in your SSL cert. When you enter the Forward Hostname/IP you can simply enter the name of the docker “service” you want to expose. If your app is not running in a docker container, you could also simply add the IP address.

By enabling “Block Common Exploits” we also add some protection features to our app. Next select the SSL cert we’ve just created and enable force SSL, HTTP/2, and HSTS if you want to.

Now, we will test if everything works fine. Simply connect to the domain and you should see that your app is accessible now. But I know there can be some errors, let’s also talk about what could go wrong.


Common error: Bad Gateway 502

This error happens when the reverse proxy can’t connect to the destination host, or doesn’t get a response. Most likely, in docker setups, the containers are not on the same network, or the destination is not correct. Make sure you’re accessing the correct IP/hostname and the NGINX proxy manager can reach this target.

Also note, that the NGINX proxy manager is running in a docker container, so using the IP address 127.0.0.1 will NOT refer to the host OS IP address, but the container’s internal address.

Another common issue is that the communication between the NGINX proxy manager and the target can’t be established because the protocol version is incorrect. Make sure you’re using the correct Scheme “HTTP” for unsecured destination sites, and “HTTPS” for secured destination sites that use a self-signed cert!

I hope this was helpful, but if you have other problems and you’re searching for help, just have a look at our Discord community.


Learn more about docker and docker-compose

6 thoughts on “NGINX Proxy Manager – How-To Installation and Configuration”

  1. Hi Christian,
    DB initalisation in Docker failed:
    2020-12-08 8:08:30 0 [Note] InnoDB: Starting shutdown…

    2020-12-08 8:08:30 0 [ERROR] Plugin ‘InnoDB’ init function returned error.

    2020-12-08 8:08:30 0 [ERROR] Plugin ‘InnoDB’ registration as a STORAGE ENGINE failed.

    2020-12-08 8:08:30 0 [Note] Plugin ‘FEEDBACK’ is disabled.

    2020-12-08 8:08:30 0 [ERROR] Could not open mysql.plugin table. Some plugins may be not loaded

    2020-12-08 8:08:30 0 [ERROR] Unknown/unsupported storage engine: InnoDB

    2020-12-08 8:08:30 0 [ERROR] Aborting

    :###
    ich benutze dein docker-compose.yml ohne Änderung
    Hast du eine Idee ?

    Reply
  2. CentOS 7 on a Virual Server. httpd is down.
    I used this docker-compose.yml

    [version: ‘3’
    services:
    app:
    image: ‘jc21/nginx-proxy-manager:latest’
    ports:
    – ’80:80′
    – ’81:81′
    – ‘443:443’
    environment:
    DB_MYSQL_HOST: “db”
    DB_MYSQL_PORT: 3306
    DB_MYSQL_USER: “npm”
    DB_MYSQL_PASSWORD: “npm”
    DB_MYSQL_NAME: “npm”
    volumes:
    – ./data:/data
    – ./letsencrypt:/etc/letsencrypt
    db:
    image: ‘jc21/mariadb-aria:10.4.12’
    environment:
    MYSQL_ROOT_PASSWORD: ‘npm’
    MYSQL_DATABASE: ‘npm’
    MYSQL_USER: ‘npm’
    MYSQL_PASSWORD: ‘npm’
    volumes:
    – ./data/mysql:/var/lib/mysql
    ](url)
    When I start docker-compose.yml without -d to see all errors. I get this error

    app_1 | ❯ Enabling IPV6 in hosts: /data/nginx
    app_1 | [1/2/2021] [3:50:42 PM] [Global ] › ℹ info Generating MySQL db configuration from environment variables
    app_1 | [1/2/2021] [3:50:42 PM] [Global ] › ℹ info Wrote db configuration to config file: ./config/production.json
    db_1 | 2021-01-02 15:50:43 3 [Warning] Access denied for user ‘npm’@’172.18.0.3’ (using password: YES)
    app_1 | [1/2/2021] [3:50:43 PM] [Global ] › ✖ error ER_ACCESS_DENIED_ERROR: Access denied for user ‘npm’@’172.18.0.3’ (using password: YES)
    db_1 | 2021-01-02 15:50:44 4 [Warning] Access denied for user ‘npm’@’172.18.0.3’ (using password: YES)

    Reply
  3. I need your help to analyze an error that is happening to me when I try to install NGINX proxy manager.

    When I follow the steps according to your tutorial it throws me a port error in which it says : 0.0.0.0:443 and 0.0.0.0:80 are already assigned…

    Note: I have installed mailcow and within the pack is Nginx alpine with that range of ports assigned … for that reason the NGINX proxy manager only works by port 81.

    What do I do?

    Reply
  4. I need your help to analyze an error that is happening to me when I try to install NGINX proxy manager.

    When I follow the steps according to your tutorial it throws me a port error in which it says : 0.0.0.0:443 and 0.0.0.0:80 are already assigned…

    Note: I have installed mailcow and within the pack is Nginx alpine with that range of ports assigned … for that reason the NGINX proxy manager only works by port 81.

    What do I do?

    Reply

Leave a Comment

I accept the Privacy Policy