Install NGINX Proxy Manager container

server docker nginx proxy
5 minutes, 24 seconds

At the end of the previous article, having configured the WordPress container, we still needed to set up NGINX Proxy Manager (NPM).

What is NPM?... It is a reverse proxy that allows us to manage traffic to our website securely and without manually editing configuration files. In other words, it allows you to access your local services or containers (such as Portainer or WordPress) using user-friendly domain names (e.g. http://tudominio.com) rather than having to remember specific IP addresses and ports. It also avoids the need to open ports on the router and leave security holes, as all external requests can be centralised to the standard ports 80 (HTTP) and 443 (HTTPS) rather than opening a different port on the network for each installed application. It also automatically installs and renews free Let’s Encrypt certificates to ensure encrypted and secure connections via the HTTPS protocol.

In short, I’m going to tell NPM that whenever there’s a request to access my domain [mixstuffs.com] (https://mixstuffs.com), which is redirected from my domain provider to my public IP address (via Cloudflare gateways, but that’s another story), it should intercept these access requests and redirect them to the Docker WordPress container to display the configured website, whilst not allowing access to any other services on my server.

Let’s start by connecting to the server via SSH and proceed with the configuration:

Instructions

1. Create the directory for the container.

As in the two previous posts on Docker, we have created a folder called “docker” to store the Compose files (container configuration files) and the folders for each container, so let’s navigate back to that folder and create the subfolders we need to get NPM up and running.

cd docker
mkdir npm
cd npm
mkdir mysql && mkdir data && mkdir letsencrypt
cd mysql
mkdir npm
cd ..

Following these instructions, we have created the “npm” folder (nginx proxy manager), which will store its configuration files within the “data” subfolder. We have also created the “mysql” folder and, within it, the “npm” subfolder, where the NGINX database will be stored. Finally, we have created the “letsencrypt” folder to store the secure certificates.

2. Create the docker-compose file.

This is the file containing the instructions for installing and initially configuring the NGINX container and its database.

sudo nano docker-compose.yml

Copy the following configuration into the compose file:

services:
  app:
    container_name: nginx-proxy-manager
    image: "jc21/nginx-proxy-manager:latest"
    networks:
      - npm
    restart: unless-stopped
    ports:
      - 80:80     # Public HTTP Port
      - 81:81     # Admin Web Port
      - 443:443   # Public HTTPS Port
      - 21:21     # Public FTP Port
    depends_on:
      - db
    environment:
  # Mysql/Mariadb connection parameters:
      - DB_MYSQL_HOST=$MYSQL_HOST
      - DB_MYSQL_PORT=$MYSQL_PORT
      - DB_MYSQL_USER=$MYSQL_USER
      - DB_MYSQL_PASSWORD=$MYSQL_PASSWORD
      - DB_MYSQL_NAME=$MYSQL_DATABASE
    volumes:
      - ~/docker/npm/ddata:/data
      - ~/docker/npm/letsencrypt:/etc/letsencrypt

  db:
    container_name: nmp-db
    image: "jc21/mariadb-aria:latest"
    networks:
      - npm
    restart: unless-stopped
    environment:
      - MYSQL_ROOT_PASSWORD=$MYSQL_PASSWORD
      - MYSQL_DATABASE=$MYSQL_DATABASE
      - MYSQL_USER=$MYSQL_USER
      - MYSQL_PASSWORD=$MYSQL_PASSWORD
      - MARIADB_AUTO_UPGRADE=1
    volumes:
      - ~/docker/mysql/npm:/var/lib/mysql/npm

networks:
  npm:
    external: true

volumes:
  npm:
    driver: local
  data:
    driver: local
  letsencrypt:
    driver: local

Under the ‘services’ section, I have included the two services that Docker will run: the first is the NGINX Proxy Manager container and the second is the database (MariaDB, as used by WordPress; since the service is already installed in the WordPress container, there is no need to install a separate database manager, which saves on resources).

Next, we have the “networks” section, where we’re specifying that the “npm” network is external (external:true). However, remember that it needs to have been created beforehand; therefore, in Portainer, we go to the networks section and create a new network called “npm”, leaving all the options at their defaults.

The final section is ‘volumes’, where we configure the database and npm folders as local volumes.

3. Create a hidden variables file.

As we saw in the previous article on WordPress, within the ‘environment’ section we have hidden the information we want to keep secure, in case someone unauthorised manages to gain access to this Compose project we are creating.

Let’s create the hidden file containing the data we want to keep hidden:

sudo nano .env

With this command, we create the hidden environment variables file and specify the value for each variable within it. Include the following in the hidden .env file (replace the ‘user’ and ‘password’ details with your own).

MYSQL_HOST=db                  # Service name
MYSQL_PORT=3306                # Database port
MYSQL_USER=npm                 # Database user
MYSQL_PASSWORD=mixstuffs       # Database password
MYSQL_DATABASE=npm             # Database name

On the same line, after the # symbol, each variable is explained. Remember that in Docker, everything to the right of the # symbol is read-only.

4. Running and accessing.

Now we run the compose command to start the containers.

docker compose up -d

Once the containers have started (check the status in Portainer), you can access the NGINX Proxy Manager web portal, create the administrator user and begin configuring the proxy.

http://ip_del_servidor:81

5. Host configuration

Having completed the previous steps, we now have NGINX Proxy Manager up and running as a reverse proxy on the server. We will now configure the proxy host so that whenever someone attempts to access the domain mixstuffs.com, our server knows where to route the request.

  • On the main screen, click on ‘Proxy Hosts’.
  • Create a new host by clicking on ‘Add Proxy Host’.
  • In ‘Domain Name’, enter the domain for which the server will respond (in my case, mixstuffs.com) and press ‘Enter’ (it’s important to press this so that it’s saved).
  • In “Host Name/Forwarding IP”, enter the server’s internal IP address and, in “Port”, enter the port number you configured in the WordPress container (8080).
  • Tick “Block Common Exploits” and “WebSockets Support”, then click the “Save” button.
  • Once the host has been created, click on the three dots on the right and select “Edit” to access the settings again.
  • Select the “SSL” tab and, under “SSL Certificate”, select “Request a new certificate with Let’s Encrypt”. Also tick the options for “Force SSL”, “HSTS Enabled” and “HTTP/2 Support”.
  • Click “Save” again.

Upon exiting the configuration, NPM will request a free SSL certificate from Let’s Encrypt and configure it so that whenever someone attempts to access the domain, they will always be directed via HTTPS, thereby avoiding secure access issues in client browsers. With this, we have now configured the local reverse proxy, and whenever an attempt is made to access the website via the domain, NPM will act as a proxy and redirect to the WordPress container, displaying the website published via the CMS.

This was written without the use of Artificial Intelligence. Thank you for reading the post.