How to distribute traffic load between docker container web servers using nginx load balancer.

I am using two AWS Instance server with different configuration. Details are:-First of all we will setup docker installation on server1 and run application with 2 docker containers.

Server HostnamePrivate Ipv4Public IPv4Configuration
dockerserver.example.com172.31.84.25054.175.218.1T2.medium + 20 GB storage + 2 core cpu + 4 GB RAM
loadserver.example.com172.31.32.2554.175.228.52T2.Micro (Default)

Note: I am using Mobaxterm for AWS instances remote access on Windows OS


On Docker-Server (54.175.218.1)

Step-1 (How to setup docker on server machine with Ubuntu OS )

we do follow official documentation for this: https://docs.docker.com/engine/install/ubuntu/

$ sudo for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
# Add Docker's official GPG key:
$ sudo apt-get update
$ sudo apt-get install ca-certificates curl gnupg
$ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Add the repository to Apt sources:
$ echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Step-2 (Manage Docker as a non-root user.)

# add a new user ram and give password to him
ubuntu@docker~$ sudo adduser ram

$ sudo vim /etc/sudoers.d/ram
ram    ALL=(ALL) NOPASSWD: /usr/bin/docker    #Give docker related authorized permission

$ sudo systemctl restart  sshd 

#  run docker container with Non-Root user 
$ sudo usermod -aG docker ram    # Make ram as a secondary group member of docker group
$ su - ram
$ docker version
$ docker info

Step-3 (How to run nginx web application on docker containers)

First we do pull nginx image from repository server like dockerhub and run container with following configuration parameters like volume, restart policy, port, neme etc.

[admin@server1 ~]$ docker pull nginx    # Pull docker nginx image
--------------------------------------------------------
# we need to add two 8080 & 8081 tcp port to firewall with admin users sudoers power
[admin@server1 ~]$ sudo firewall-cmd --add-port=8080/tcp --permanent
success
[admin@server1 ~]$ sudo firewall-cmd --add-port=8081/tcp --permanent
success

# Reload firewall-cmd
[admin@server1 ~]$ sudo firewall-cmd --reload
success
--------------------------------------------------------
# now switch to ram user and run nginx web containers
[admin@server1 ~]$ su - ram
ram@dockerserver:~$ docker run --name web-nginx1 -p 8081:80 --restart=always -v vol1:/usr/share/nginx/html -d nginx
6787f299798d6b6d47171e0995d0532ee8bdd352bba6407b561b4e6b7d4400b4

ram@dockerserver:~$ docker run --name web-nginx2 -p 8082:80 --restart=always -v vol1:/usr/share/nginx/html -d nginx
5bcf77f85e4a827579261f7251a7abce698f56f00a1e653fd59caeae677d4c90

ram@dockerserver:~$ ls /var/lib/docker/volumes/vol1/_data/
50x.html  index.html
ram@dockerserver:~$ sudo echo "<h1> This is nginx web container1 </h1>" >> /var/lib/docker/volumes/vol1/_data/index.html

ram@dockerserver:~$ sudo ls /var/lib/docker/volumes/vol2/_data/
50x.html  index.html
ram@dockerserver:~$ sudo echo "<h1> This is nginx web container2 </h1>" >> /var/lib/docker/volumes/vol2/_data/index.html

root@dockerserver:~# docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                                   NAMES
81abf80b6307   nginx     "/docker-entrypoint.…"   9 minutes ago    Up 9 minutes    0.0.0.0:8082->80/tcp, :::8082->80/tcp   web-nginx2
83dec3eeac1c   nginx     "/docker-entrypoint.…"   10 minutes ago   Up 10 minutes   0.0.0.0:8081->80/tcp, :::8081->80/tcp   web-nginx1


ram@dockerserver:~& docker exec -it 81abf80b6307 bash
root@81abf80b6307:/# cat /usr/share/nginx/html/
50x.html    index.html

root@81abf80b6307:/# cat /usr/share/nginx/html/index.html
<h1> This is nginx web container2 </h1>

root81abf80b6307:/# read escape sequence
ram@dockerserver:~# docker exec -it 83dec3eeac1c bash

root@83dec3eeac1c:/# cat /usr/share/nginx/html/index.html
<h1> This is nginx web container1 </h1>

Access web page using Docker server public ip address with 8081 and 8082 port number: Example:

http://54.175.218.1:8081

http://54.175.218.1:8082


On Load-Server (34.227.83.161)

Step-1 (How to configure nginx Load Balancer on "load-server" to distribute trrafic requests load between docker containers on "Docker-Server" )

$ sudo apt-get update
$ sudo apt-get install nginx
$ sudo systemctl restart nginx
$ sudo systemctl enable nginx
$ sudo vi /etc/nginx/conf.d/load.conf

upstream backend {            # backend is a group name for below mentioned servers 
    server 54.175.218.1:8081;    # Public IP of Docker-Server:port
    server 54.175.218.1:8082;
        }

server {
    listen 80; # You may want to specify the appropriate port    
    server_name 54.175.228.52; # Load-Server public IP (nginx-load-balancer server running on)

location / {
     proxy_pass http://backend;    
        }
    }
$ nginx -t    # to check nginx.conf configuration is correct or not
$ sudo systemctl restart nginx

Step-2 (Check nginx Load-Server to traffic distribution working or not)

Go to browser and paste : public-ip-of-load-server

http://54.175.228.52 and refresh the browser continusely to check


Reference: