How to set up a reverse proxy for multiple docker containers using NGINX ?

Anas EL Fatihi
6 min readJun 27, 2021

--

I will share with you a docker configuration for NGINX server to handle multiple containers with subdomains.

For this tutorial i will use two basic Hello world NodeJs applications.In the first section we will see the “Hello world” NodeJs app.In the second section we will configure docker for our two apps.In the third section we will configure NGINX as a reverse proxy for our multiple subdomains, we will run the first app with this domain : app1.mydomain.com and the second one in app2.mydomain.com

PS : In this article i will be using a local DNS resolution: i will modify my host file so the domain name resolution will be done locally without making any request to any DNS server.you can use the same configuration if you are using it for your hosted container in the cloud, you will just need to register your domain name for your container and that’s it.

Section 1 : Creating the NodeJs App

In this section we will create a basic Hello World NodeJs app.I will give you a snippet of the main method that we will be using to identify which app is running.To create a brand new NodeJS app i suggest you follow this great article.

Our server entry file will be index.js for both apps:

App number 1:

NodeJs server entry file
index.js: App number 1

App number 2:

index.js: App number 2

Both apps are running on port 3000, if we run one of them we will see that the app is running successfully, don’t try to make them run simultaneously because you will get a port conflict.i’m using the same port on purpose, we will see this later on when we will be using docker.

NodeJs Hello world app
App number 1

Section 2 : Configuring Docker for our two apps

Now that we have our two Hello World apps built, we will configure docker and run them in separate containers.

To install docker follow the official documentation here.

In our root folder, for both apps, we will create a Dockerfile :

Docker file for both apps

With this config file: we are using the latest LTS version of Node available in Docker hub.Next we create a directory to hold the application code inside the docker image, this will be the working directory for our application.After that we are installing our dependencies with NPM and we copy all our files into our working directory in the docker image.Finally we are exposing the 8080 docker container port and we run our app inside our docker image.

To run our container, we need to build our images and give them a tag name, to do that open a terminal in your app folder where the the Dockerfile is located and run the build command for each app.

docker build . --tag firstapp:1.0

docker build . --tag secondapp:1.0

Now to run our images on different containers we will use the build command as shown below :

docker run — publish 81:3000 — detach — name firstapp firstapp:1.0

docker run — publish 82:3000 — detach — name secondapp secondapp:1.0

If you run the docker ps command you will see that the containers are actually runing and the port are binded from our machine to the docker container.

Docker ps result

Now our two docker apps are running locally on our machine but not accessible from any other machine( we will did to this in the next section ):

App number 1 running locally
App number 2 running locally

The two apps are running on our machine but they are not accessible from the internet, so the next step will be to transform our working machine to a web server.

Section 3 : Configuring NGINX

To install NGINX, follow the official document right here.

After installing NGINX we will configure our host file so we can simulate a DNS resolution.If you already have a domain just make sur you put the name servers of your host provider in the correct fields of your DNS adresse provider like any basic configuration and you will be fine.You can skip this part if you have a domain name already configured.

Here are the two lines added to my /etc/hosts file:

DNS configuration

PS:Note that i have chosen app1.mydomain.com to the first app and app2.mydomain.com for the second.

The path for windows users is : c:\Windows\System32\Drivers\etc\hosts.To flush the dns : ipconfig /flushdns

linux users : /etc/hosts : don’t forget to flush the dns : dscacheutil -flushcache

TIP :To check if you have correctly configured the domains, use the dig [ domainName] command to check if the configuration is correct.

Now that we are done configuring our domains, lets configure NGINX server.The config file is is nginx.conf. Just delete it, we will create a new one from scratch.

NGINX config file

With this configuration we are saying to NGINX that if any coming request demanding ,for example, app1.mydomain.com will be redirected to localhost:81.The result is that any request with that domain( app1.mydomain.com) name will be redirected to our first docker container and any request with the other domain name(app2.mydomain.com) will be redirected to our second docker container.

Note that this configuration is very minimalist, we are not handling a lot of aspect like : multiple config files, secure request (SSL),404,Logs,…

To check is our config file is ok use this command and you will get something like this (if everything is done correctly) and then restart NGINX (mac users: sudo nginx -s reload ):

Success config file

Now, that everything is well configured, lets test if our apps are accessible from our two domains:

App number 1
App number 2

Conclusion

In this article we have seen how to build a simple reverse proxy using NGINX web server and two docker containers containing basic NodeJs Apps.this configuration can be very useful when you are building a micro services apps.

We can do more with our configuration like adding a load balancer, secure the traffic using ssl certificates, create multiple config files, work on logs,…

If you want to translate, or republish this article on your blog, website, or publication, please drop me a note on my email anaselfatihi1@gmail.com, I usually say yes.

--

--

Anas EL Fatihi
Anas EL Fatihi

No responses yet