A Guide to NGINX Load Balancing for Dockerized Node.js Apps
10.3.2024

Introduction
In this guide we are going to learn how to use NGINX to load balance a Dockerized Node.js application. We will start by creating a simple Node.js application and then we will create a Docker image for it. We will then create a simple NGINX configuration to load balance the application (also we will use Docker for nginx 💪).
prerequisites
You should already know about Docker, nodesjs and nginx
Step 1: Create a simple Node.js application
create a new directory and create a file called app.js
and add the following code to it:
const express = require("express");
const app = express();
const os = require("os");
const hostname = os.hostname();
app.get("/", (req, res) => res.send("Hello from " + hostname));
app.listen(8080, () => console.log("listening on port 8080 on " + hostname));
Then run this command to initiate npm and install express:
npm init -y
npm install express
Step 2: Create a Docker image for the Node.js application
Create a file called Dockerfile
in a root directory and add the following code to it:
FROM node:20.11.1
WORKDIR /home/node/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8080
CMD ["node", "app.js"]
step 3: Build the Docker image
Run the following command to build the Docker image:
docker build -t node-app .
step 4: Write the NGINX configuration
Create a file called nginx.conf
in the root directory and add the following code to it:
http {
upstream nodebackend {
# we can point to the conatiner name if we use user-defined bridge network in docker
server nodeapp1:8080;
server nodeapp2:8080;
server nodeapp3:8080;
}
server {
listen 8080;
location / {
proxy_pass http://nodebackend/;
}
}
}
events {
}
You can create create a custom dockerfile for nginx and add the
nginx.conf
file to it. But for simplicity we will use the default nginx image and mount thenginx.conf
file to it via command line.
step 5: Really Important Step
If you look closely at the nginx config file, you will see that we are using the container names as the server names. This is only possible if you use user-defined bridge network .
Here is how you can create a user-defined bridge network:
docker network create -d bridge load-balance
-d
will specify the driver to use for the network. In this case, we are using the bridge driver. And the name of the network is load-balance
.
You can verify that the network has been created by running the following command:
docker network ls
step 6: Run 3 Node.js application via Docker
3 instances of the Node.js application will be running on different ports. We will use the --network
flag to specify the network to use.
3 is just an example, you can run as many instances as you want.
docker run --name nodeapp1 --hostname nodeapp1 -p 2222:8080 --network load-balance -d node-app
docker run --name nodeapp2 --hostname nodeapp2 -p 3333:8080 --network load-balance -d node-app
docker run --name nodeapp3 --hostname nodeapp3 -p 4444:8080 --network load-balance -d node-app
--name
is used to specify the name of the container and this flag will help us to use the name of container in nginx.conf
file instead of the ip address.
--hostname
is used to specify the hostname of the container, if you see the the app.js
file we are using os.hostname()
to get the hostname of the container. The reason I used this flag is to prove that load balancing is happening when you refresh the page.
At this point you can visit http://localhost:2222
, http://localhost:3333
and http://localhost:4444
and you will see the response from the Node.js application.
step 7: Run the NGINX container
Run the following command to run the nginx container:
docker run --name nginx --hostname ng1 -p 80:8080 -v ./nginx.conf:/etc/nginx/nginx.conf --network load-balance -d nginx
Now visit http://localhost
and you will see the response from the Node.js application. If you refresh the page you will see the response from different containers. This is because the load balancing is happening.
Conclusion
In this guide we learned how to use NGINX to load balance a Dockerized Node.js application. We created a simple Node.js application and then we created a Docker image for it. We then created a simple NGINX configuration to load balance the application. We used Docker for nginx and we used user-defined bridge network to make the containers communicate with each other.