Logo AppDev24 Login / Sign Up
Sign Up
Have Login?
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.
Login
New Account?
Recovery
Go to Login
By continuing you indicate that you agree to Terms of Service and Privacy Policy of the site.
Docker

Docker Nginx Load Balancer

Updated on Aug 15, 2024

Are you looking to set up a Nginx container using Docker on your MacOS machine? Look no further! In this article, we'll walk you through the process of creating and configuring a Docker Nginx container, including setting nginx configuration as Load Balancer, http redirection & ssl/tls termination.

Create Self Signed Certificate

Pre-requisite: openssl must be installed in MacOS

openssl req -x509 -nodes -days 365 \
    -subj "/C=DE/ST=Berlin/L=Berlin/O=appdev24/OU=dev/CN=nginx.demo" \
    -newkey rsa:4096 -keyout selfsigned.key \
    -out selfsigned.crt

-subj switch option:

  • Country Name (2 letter code): DE
  • State or Province Name (full name): Berlin
  • Locality Name (city): Berlin
  • Organization Name (company): appdev24
  • Organizational Unit Name (department): dev
  • Common Name (server FQDN): nginx.demo

Update hosts file

sudo vi /etc/hosts

# Append the server entry
127.0.0.1	nginx.demo

Create Nginx configuration

nginx-loadbalancer.conf

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;
    
    sendfile            on;
    keepalive_timeout   65;


    # HTTP Redirect
    server {
        listen          80 default_server;
        listen          [::]:80 default_server;
        server_name     _;
        return 301 https://$host$request_uri;
    }


    # HTTP Load Balancing
    upstream static {
        server host.docker.internal:8090;
        server host.docker.internal:8092;
    }


    # SSL/TLS Termination
    server {
        listen 443 ssl;
        listen [::]:443 ssl;

        server_name     nginx.test;
        root            /usr/share/nginx/html;
        index           index.html;
        
        ssl_session_cache   shared:SSL:10m;
        ssl_session_timeout 4h;
        
        ssl_protocols               TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_ciphers                 HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers   off;

        ssl_certificate         /etc/ssl/certs/selfsigned.crt;
        ssl_certificate_key     /etc/ssl/private/selfsigned.key;

        # Proxy
        location / {
            proxy_http_version 1.1;
            proxy_cache_bypass $http_upgrade;

            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_pass http://static;
        }

        # Basic Status Info
        location /stub_status {
            stub_status on;
        }
    }
}

NGINX offers multiple load balancing methods, including round-robin, least connections, ip hash, etc.

Create Demo Webpage

app1.html

<!DOCTYPE html>
<html>
<head>
    <title>NGINX- Load Balancer</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
    <style>
        body,
        html {
            height: 100%
        }
        .bgimg {
            background-image: url('https://images.unsplash.com/photo-1451187580459-43490279c0fa');
            min-height: 100%;
            background-position: center;
            background-size: cover;
        }
    </style>
</head>
<body>
    <div class="bgimg w3-display-container w3-animate-opacity w3-text-white">
        <div class="w3-display-topleft w3-padding-large w3-xlarge">
            Docker
        </div>
        <div class="w3-display-middle">
            <h1 class="w3-jumbo w3-animate-top">NGINX</h1>
            <hr class="w3-border-grey" style="margin:auto;width:40%">
            <p class="w3-large w3-center">As Load Balancer</p>
            <p class="w3-large w3-center">Server: static-app1</p>
        </div>
    </div>
</body>
</html>

Create a copy of the above html file as app2.html and replace the following:

<p class="w3-large w3-center">Server: static-app1</p>
WITH
<p class="w3-large w3-center">Server: static-app2</p>

Create Docker Compose file

loadbalancer-docker-compose.yml

version: '3.9'

services:
  nginx-loadbalancer:
    # Apple M1 Chip
    platform: linux/amd64
    image: nginx:latest
    container_name: nginx-loadbalancer
    restart: always
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./nginx-loadbalancer.conf:/etc/nginx/nginx.conf:ro
      - ./selfsigned.crt:/etc/ssl/certs/selfsigned.crt:ro
      - ./selfsigned.key:/etc/ssl/private/selfsigned.key:ro
    networks:
      - backend-network

  static-app1:
    # Apple M1 Chip
    platform: linux/amd64
    image: nginx:latest
    container_name: static-app1
    restart: always
    ports:
      - 8090:80
    volumes:     
      - ./app1.html:/usr/share/nginx/html/index.html:ro
    networks:
      - backend-network

  static-app2:
    # Apple M1 Chip
    platform: linux/amd64
    image: nginx:latest
    container_name: static-app2
    restart: always
    ports:
      - 8092:80
    volumes:     
      - ./app2.html:/usr/share/nginx/html/index.html:ro
    networks:
      - backend-network

networks:
  backend-network:
    driver: bridge

Start the Container

Now that we have our configuration and Docker compose file set up, it's time to start the container! Run the following command:

docker-compose -f loadbalancer-docker-compose.yml up -d

This will start the containers in detached mode, meaning they will run in the background.

Test Nginx Loadbalancer Container

Once the container is running, we can test our webserver by browsing to https://nginx.demo. You will observer that the response is rendered via both the servers in a round-robin fashion.

Optionally you can download the self signed certificate from
Chrome > Developer Tools > Security Tab > View Certificate
and import into MacOS System Keychain to Always Trust the self signed certificate and avoid the certificate warning.

Stop the Container

Finally, we can stop the containers by running the following command:

docker-compose -f loadbalancer-docker-compose.yml down

This will stop the containers and remove it from memory.

That's it! We've successfully created and configured a Docker Nginx container as a Loadbalancer along with SSL/TLS Termination and HTTP Redirect.

PrimeChess

PrimeChess.org

PrimeChess.org makes elite chess training accessible and affordable for everyone. For the past 6 years, we have offered free chess camps for kids in Singapore and India, and during that time, we also observed many average-rated coaches charging far too much for their services.

To change that, we assembled a team of top-rated coaches including International Masters (IM) or coaches with multiple IM or GM norms, to provide online classes starting from $50 per month (8 classes each month + 4 tournaments)

This affordability is only possible if we get more students. This is why it will be very helpful if you could please pass-on this message to others.

Exclucively For Indian Residents: 
Basic - ₹1500
Intermediate- ₹2000
Advanced - ₹2500

Top 10 Articles