Load-balancing using docker and nginx

Let me be clear this article is not a tutorial on NGINX or Docker. Just how to setup Load-balancing using both (Nginx and Docker). I will be assuming pre-requiste knowledge of both subjects. In this article, we will be looking at how to achieve load-balancing using nginx and docker. well, what exactly is nginx and what is docker ? Understanding Load-balancing - A website can have millions of requests, which can cause a bottleneck and make the latency (response time) slow. We need a way to handle the millions of request, to do this we need to increase the number of servers. NGINX Nginx - is a web server that serves us web content. Nginx can forward a user request to an available server. This is called (load balancing). Nginx chooses which server will handle user request at each time. nginx.conf - the file to setup nginx http { upstream backendserver { # here, we can specify all the backend url, that we have. server 127.0.0.1:9000; server 127.0.0.1:9001; server 127.0.0.1:9002; } server { listen 8080; location / { proxy_pass http://backendserver/; } } } cd nginx - nginx To start the nginx server Docker Docker - is a way to package your application, as a developer. This way another developer can quickly setup same application on their system without running into a lot of issues and errors along the way. A dockerfile comes with all of the necessary instructions needed to setup said application. Now, Docker can host a nodejs web-server inside of a container for you, this way we can run multiple servers at once, just by spinning up multiple instances of docker containers. I ran into a major problem when using dockerfile to spin up my containers. Problem 1 The index.js file has changed, do I need to rebuild the dockerfile and if I do that, would I need to re-create new containers based off on the new docker image Answer The answer to that question was Yes, if the index.js file has changed, you need to rebuild the Docker image to include the updated code. After rebuilding the Docker image, you will need to recreate the containers based on the new image to run the updated code. Doing this everytime feels repetitive and tiring. Problem 2 Is there a way to automatically restarting your container every time a file has changed without the need to rebuild your image each time ? Answer The answer to that question was Yes, we have two ways or options to do that Docker Compose Mount Volumes I would be looking into the second option for today, you can use Docker volumes to mount your local directory into the container. This way, any changes you make to your local files will be reflected in the running container without needing to rebuild the image. So, we need a dockerfile that would contain information about the web-server. # Uses node version 16 as our base image FROM node:16 # Create app directory inside the docker image WORKDIR /usr/src/app # Copy package.json into the app directory of the docker image COPY package.json ./ # Install dependencies RUN npm install # Copy our entire code into the app directory of the docker image COPY . . # Install nodemon globally RUN npm install -g nodemon # expose port EXPOSE 3000 # Run app CMD ["nodemon", "--legacy-watch", "index.js"] I need to explain the dockerfile a bit # Run app CMD ["nodemon", "--legacy-watch", "index.js"] This will ensure that nodemon automatically restarts the container when we make changes to our nodejs code locally. Now, we can carry on. Build the Docker image: docker build -t node-application . Run the container with a volume mount: We would have two docker containers running, so we would run this command twice. (-e CONTAINER_NAME=web1): This is the environment variable to help us distinguish between each container. (--name web1): This is the name of the container. (-p 9001:3000): This is port-mapping, we expose the container's port (3000) to our local computer port (9000). docker run -d -p 9001:3000 --name web1 -v C:\Users\PC\Documents\Documents\2025\nginx_tuts\server:/usr/src/app -e CONTAINER_NAME=web1 node-application Nodejs const express = require("express"); const app = express(); app.get("/", (req, res) => { console.log(`say nigga ${process.env.CONTAINER_NAME} hit`); res.send(`Hello World from ${process.env.CONTAINER_NAME}`); }); app.listen(3000, () => { console.log("Server is running on port 3000"); }); This is how my basic nodejs-express server was setup Thank you, please follow me

Mar 17, 2025 - 17:26
 0
Load-balancing using docker and nginx

Let me be clear this article is not a tutorial on NGINX or Docker. Just how to setup Load-balancing using both (Nginx and Docker). I will be assuming pre-requiste knowledge of both subjects.

In this article, we will be looking at how to achieve load-balancing using nginx and docker. well, what exactly is nginx and what is docker ?

Image description

Understanding Load-balancing - A website can have millions of requests, which can cause a bottleneck and make the latency (response time) slow. We need a way to handle the millions of request, to do this we need to increase the number of servers.

NGINX

Nginx - is a web server that serves us web content.

Nginx can forward a user request to an available server. This is called (load balancing). Nginx chooses which server will handle user request at each time.

nginx.conf - the file to setup nginx


http {

upstream backendserver {
        # here, we can specify all the backend url, that we have.

        server 127.0.0.1:9000;
        server 127.0.0.1:9001;
        server 127.0.0.1:9002;
    }

server {
listen 8080;

location / {
            proxy_pass http://backendserver/;
        }

}

}

cd nginx - nginx

To start the nginx server

Docker

Docker - is a way to package your application, as a developer. This way another developer can quickly setup same application on their system without running into a lot of issues and errors along the way. A dockerfile comes with all of the necessary instructions needed to setup said application.

Now, Docker can host a nodejs web-server inside of a container for you, this way we can run multiple servers at once, just by spinning up multiple instances of docker containers.

I ran into a major problem when using dockerfile to spin up my containers.

Problem 1

The index.js file has changed, do I need to rebuild the dockerfile and if I do that, would I need to re-create new containers based off on the new docker image

Answer

The answer to that question was Yes, if the index.js file has changed, you need to rebuild the Docker image to include the updated code. After rebuilding the Docker image, you will need to recreate the containers based on the new image to run the updated code.

Doing this everytime feels repetitive and tiring.

Image description

Problem 2

Is there a way to automatically restarting your container every time a file has changed without the need to rebuild your image each time ?

Answer

The answer to that question was Yes, we have two ways or options to do that

  1. Docker Compose

  2. Mount Volumes

I would be looking into the second option for today, you can use Docker volumes to mount your local directory into the container. This way, any changes you make to your local files will be reflected in the running container without needing to rebuild the image.

So, we need a dockerfile that would contain information about the web-server.

# Uses node version 16 as our base image
FROM node:16

# Create app directory inside the docker image
WORKDIR /usr/src/app

# Copy package.json into the app directory of the docker image
COPY package.json ./

# Install dependencies
RUN npm install

# Copy our entire code into the app directory of the docker image
COPY . .


# Install nodemon globally
RUN npm install -g nodemon

# expose port
EXPOSE 3000

# Run app
CMD ["nodemon", "--legacy-watch", "index.js"]

Image description

I need to explain the dockerfile a bit

# Run app
CMD ["nodemon", "--legacy-watch", "index.js"]

This will ensure that nodemon automatically restarts the container when we make changes to our nodejs code locally.

Now, we can carry on.

  1. Build the Docker image:
 docker build -t node-application .
  1. Run the container with a volume mount:

We would have two docker containers running, so we would run this command twice.

  • (-e CONTAINER_NAME=web1): This is the environment variable to help us distinguish between each container.

  • (--name web1): This is the name of the container.

  • (-p 9001:3000): This is port-mapping, we expose the container's port (3000) to our local computer port (9000).

docker run -d -p 9001:3000 --name web1 -v C:\Users\PC\Documents\Documents\2025\nginx_tuts\server:/usr/src/app -e CONTAINER_NAME=web1 node-application

Nodejs

const express = require("express");

const app = express();

app.get("/", (req, res) => {
  console.log(`say nigga ${process.env.CONTAINER_NAME} hit`);
  res.send(`Hello World from ${process.env.CONTAINER_NAME}`);
});


app.listen(3000, () => {
  console.log("Server is running on port 3000");
});

This is how my basic nodejs-express server was setup

Image description

Thank you, please follow me