Easily Deploy a Nginx Reverse Proxy using Docker

In this tutorial, we will show you how to use Docker to quickly and easily deploy an Nginx-based reverse proxy on your system.

NGINX Reverse Proxy Docker Compose

A reverse proxy is a service that sits in front of other web servers and handles requests from clients. These requests are then forwarded to the web servers, and the responses are sent back to the client. The end user is left entirely unaware of this whole process.

There are various reasons why you might want to set up a reverse proxy. One is to easily run multiple services under one server even when they might be dependent on a different web server. Another is easily providing HTTPS support. Many self-hosted services, especially ones that run within a Docker container, are set up only to handle HTTP.

Luckily, thanks to some very neat and easy-to-use Docker containers, setting up an Nginx reverse proxy has never been easier.

With Docker, you can easily have an Nginx-powered reverse proxy up and running with just a few lines of configuration. Routing your other containers through it just requires adding a few extra lines to their Compose file.

In particular, we will be using the Nginx Proxy Docker container. You can find more about this container about checking out its official GitHub page.

Setting up an Nginx Reverse Proxy using Docker.

Over the following sections, we will walk you through the process of setting up an Nginx reverse proxy using Docker. We will also show you an example of how to modify an existing container to run through your proxy server.

Before proceeding any further, you must have a domain name in mind that you intend to route through your reverse proxy. Additionally, it would help if you also had this domain pointed towards your server.

Finally, if you are running this from your home network, ensure you have ports 80 and 443 forwarded to your server. The NGINX proxy will use these and must be open for the SSL certificate to be generated.

Installing Docker on your Machine

1. Before starting with this tutorial, you will be required to have Docker installed on your machine.

If you haven’t yet installed this runtime, we highly recommend following our Docker installation guide

https://pimylifeup.com/linux-docker-install/

Setting up your System for the Reverse Proxy

2. Our next step is to use the mkdir command to create a directory to store the Docker Compose file for the NGINX Reverse proxy.

We like to keep all of our Docker Compose files within the “/opt/stacks/” directory as it helps keep them organized. Additionally, it will also work with the Dockge management tool out of the box.

sudo mkdir -p /opt/stacks/reverseproxy/

3. After making a directory to store the proxy configuration, change to it using the cd command within the terminal.

cd /opt/stacks/reverseproxy/

Writing a Docker Compose file for your Nginx Reverse Proxy

4. Our next step is to write a Docker Compose file that will manage the Nginx reverse proxy on your system.

You can begin writing this file using the following command in the terminal.

sudo nano compose.yaml

5. Within this Docker Compose file, we will set up two separate services. The first Docker container is the Nginx reverse proxy. This is what your other apps will be routed through.

The other component is a companion container that will handle requesting Let’s Encrypt certificates for your services. This is critical for having proper HTTPS support and stops you from relying on insecure self-signed certificates.

While filling out this file, you must replace a placeholder value with your own.

  • <EMAIL>: Replace this with an email where Let’s Encrypt can contact you. This will be used in various cases, such as notifying you of an expiring certificate.

We are doing a couple of extra and super important things within this Compose file.

First, we specifically specify a network called “nginx-reverse-proxy” on which the Nginx Reverse proxy container will run. We need to do this as every service we want to be routed through this proxy must be a member of this network.

One thing you may have noticed from this file is that we are setting up two volumes. These volumes allow the certificates generated by the companion Docker container and read in by the Nginx reverse proxy container.

services:
  nginx-proxy:
    image: nginxproxy/nginx-proxy
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - certs:/etc/nginx/certs
      - html:/usr/share/nginx/html
      - /var/run/docker.sock:/tmp/docker.sock:ro
    labels:
      - com.github.nginx-proxy.nginx
    networks:
      - nginx-reverse-proxy

  nginx-proxy-acme:
    image: nginxproxy/acme-companion
    restart: always
    depends_on:
       - "nginx-proxy"
    environment:
      DEFAULT_EMAIL: <EMAIL>
    volumes:
      - certs:/etc/nginx/certs
      - html:/usr/share/nginx/html
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - nginx-reverse-proxy

networks:
  nginx-reverse-proxy:
    name: nginx-reverse-proxy

volumes:
  html:
  certs:

6. After filling out this file, you can save and quit out of Nano by pressing CTRL + X, Y, and then ENTER.

Starting up the NGINX Reverse Proxy Container

7. All you need to do now to start up the NGINX reverse proxy using Docker is to run the following command within the terminal.

With this command, Docker will read in the Compose file we wrote and start up each container referenced within it. This process should only take a couple of minutes.

Once it has started, the container will continually poll Docker to see when other containers have started. It will check each container to see if the “VIRTUAL_HOST” environment variable has been defined. If it finds this variable, it will automatically reconfigure Nginxto act as a reverse proxy for that service using the specified domain name.

docker compose up -d

Modifying Containers to Run Through Your Proxy

8. With the Docker container for the Nginx Reverse Proxy now up and running, you will need to modify any container you intend on routing through it.

To give you an example of how this is done, we will modify the Compose file for our Uptime Kuma Docker container.

Before we begin to edit the Compose file, we will change to the directory where it was written using the cd command.

cd /opt/stacks/uptimekuma

9. Before we begin editing this file, let us quickly go over the values you must add to the containers you want to route through the Nginx reverse proxy.

Each container you want to run through your reverse proxy will need at least two environment variables to be set.

  • VIRTUAL_HOST: This variable tells the Nginx proxy the hostname it should use for your service. This should be the domain name you want to use.

    For example, it might be “uptimekuma.pimylifeup.com“.
  • LETSENCRYPT_HOST: Typically, in most people’s cases you will want to set this value to
  • VIRTUAL_PORT: This is the only optional environment variable. It allows you to specify the exact port that should be routed through this proxy.

    If your service only exposes a single port, you don’t need to worry about setting this as the proxy will attempt to auto detect it.

Once you are ready, open the Compose file for editing using the following command in the terminal.

sudo nano compose.yml

10. Below is what our Compose file looks like before we make any changes.

We will need to change a few things with this file, and we will go over them. These should be easy enough to apply to your own containers.

  • First, we must add the environment variables discussed in the previous step. These will help the Nginx Reverse Proxy know how to route traffic to your other Docker containers.
  • Secondly, we must add this container to our “nginx-reverse-proxy” network.

Luckily, setting all these values are pretty simple, even more so if you are using a Docker Compose file.

services:
  uptime-kuma:
    image: louislam/uptime-kuma:1
    volumes:
      - ./data:/app/data
      - /var/run/docker.sock:/var/run/docker.sock
    ports:
      - 3001:3001
    restart: unless-stopped

Removing the Existing Port Declaration

11. One thing you will want to do is remove the declaration for the port you intend on routing through your Nginx Reverse proxy. Removing the declaration ensures the proxy will be the only way to reach the container.

In our case, Uptime Kuma uses port 3001, and that is the one we want to route through the proxy.

    ports:
      - 3001:3001

As we have no other port declarations, our example file will end up looking like what we have shown below.

services:
  uptime-kuma:
    image: louislam/uptime-kuma:1
    volumes:
      - ./data:/app/data
      - /var/run/docker.sock:/var/run/docker.sock
    restart: unless-stopped

Adding the Environment Variables

12. With the port removed, our next step is to add the environment variables that the Nginx Reverse proxy container will look for.

You must define these environment variables under each container you want routed through your proxy.

For our example, the “VIRTUAL_HOST” and “LETSENCRYPT_HOST” variables will be set to the domain name we intend on using which is “uptimekuma.pimylifeup.com“.

We will also set the “VIRTUAL_PORT” variable to port 3001, which Uptime Kuma operates on. The Nginx Proxy Docker container we are using will attempt to select the right port, but it helps to nudge it in the right direction.

    environment:
        VIRTUAL_HOST: uptimekuma.pimylifeup.com
        LETSENCRYPT_HOST: uptimekuma.pimylifeup.com
        VIRTUAL_PORT:3001

Below is an example of what a Compose file will look like after adding the environment variables.

services:
  uptime-kuma:
    image: louislam/uptime-kuma:1
    volumes:
      - ./data:/app/data
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
        VIRTUAL_HOST: uptimekuma.pimylifeup.com
        LETSENCRYPT_HOST: uptimekuma.pimylifeup.com
        VIRTUAL_PORT: 3001
    restart: unless-stopped

Adding your Docker Container to the Reverse Proxy Network

13. To get your Docker container to route through your Nginx Reverse proxy, we must ensure it is a member of the same network.

This is fairly simple, as we simply need to add the “networks” option to set this container to join the “nginx-reverse-proxy” network.

Every Docker service you want routed through the proxy must be a member of this network. The proxy won’t be able to handle communications between the proxy and your service without this.

    networks:
        - nginx-reverse-proxy

After adding the “networks” line to our Uptime Kuma service, it will end up looking like what we have shown below.

services:
  uptime-kuma:
    image: louislam/uptime-kuma:1
    volumes:
      - ./data:/app/data
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
        VIRTUAL_HOST: uptimekuma.pimylifeup.com
        LETSENCRYPT_HOST: uptimekuma.pimylifeup.com
        VIRTUAL_PORT: 3001
    networks:        
      - nginx-reverse-proxy
    restart: unless-stopped

14. While we now have the Uptime Kuma container using the “nginx-reverse-proxy” we need to tell Docker that this is an external network that doesn’t belong to the containers specified here.

This is as easy as adding the following block to the bottom of your Compose file. If you have an existing “networks” block, add the “nginx-reverse-proxy” part to it.

networks:
  nginx-reverse-proxy:
    external: true

Finally, with all of our required changes, our file looks like the following.

Here, we have the environment variables set, which tells the Nginx Reverse Proxy container what domain name to use. We have also set the network up to route through the same one our proxy does.

services:
  uptime-kuma:
    image: louislam/uptime-kuma:1
    volumes:
      - ./data:/app/data
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
        VIRTUAL_HOST: uptimekuma.pimylifeup.com
        LETSENCRYPT_HOST: uptimekuma.pimylifeup.com
        VIRTUAL_PORT: 3001
    networks:        
      - nginx-reverse-proxy
    restart: unless-stopped

networks:
  nginx-reverse-proxy:
    external: true

Saving your Changes and Restarting the Container

14. After you have finished adding these variables, save and quit by pressing CTRL + X, Y, and then ENTER.

15. With those changes, all you need to do to get the NGINX reverse proxy to start routing traffic to it is restarting the container.

One of the simplest ways to do this when dealing with a Docker Compose file is to run the following command.

Once Docker declares your container “healthy,” the NGINX reverse proxy will automatically reconfigure itself to begin routing traffic from your domain name to the service.

Additionally, if you use the Lets Encrypt companion container, an SSL certificate will automatically be fetched and set up for your service.

docker compose up -d

Conclusion

Hopefully, by getting to this point in the guide, you will have successfully set up the NGINX Reverse proxy using Docker.

This container is a great way to route your various services through a single point. It is also one of the easiest ways to add HTTPS support to containers that might only provide an HTTP connection.

Please feel free to leave a comment below if you have any questions or concerns about setting up your reverse proxy with a Docker container.

If you found this Docker guide to be helpful, we highly recommend taking some time to explore our many other Docker guides.

Leave a Reply

Your email address will not be published. Required fields are marked *