Nginx For Beginners

Intermediate Config

Demo Load Balancer

In this tutorial, you'll learn how to configure Nginx as a load balancer using three common algorithms:

  1. Round Robin: Distributes requests evenly across all backend servers.
  2. Weighted Round Robin: Assigns traffic proportionally based on server weights.
  3. IP Hash: Routes each client IP to the same backend to maintain session persistence.

The image illustrates a Round Robin load balancing algorithm using NGINX, distributing requests to two Apache web servers.

The image illustrates a weighted round robin load balancing algorithm using NGINX, distributing traffic to two Apache web servers with different weights.

The image illustrates an IP Hash algorithm used in load balancing, showing a load balancer directing traffic to multiple web servers based on IP addresses.

Load Balancing Algorithm Comparison

AlgorithmBehaviorUse Case
Round RobinCycles through all servers equallySimple distribution without session affinity
Weighted Round RobinTraffic proportionate to configured server weightsDiffering server capacities or performance levels
IP HashRoutes same client IP to the same backendSession persistence without cookies or headers

Environment Setup

We have three Ubuntu nodes in our test lab:

  • nginx: Nginx load balancer (192.230.202.10)
  • node01 & node02: Apache backend servers

On each backend, Apache is running and UFW is active but only port 22 is open by default:

# On node01 (repeat on node02)
root@node01:~# systemctl status apache2
● apache2.service - The Apache HTTP Server
   Active: active (running) ...

root@node01:~# ufw status
Status: active

To                         Action    From
--                         ------    ----
22/tcp                     ALLOW     Anywhere
22/tcp (v6)                ALLOW     Anywhere (v6)

Allow Only the Load Balancer

For security, restrict HTTP access so only the load balancer (192.230.202.10) can reach port 80 on your backends.

# On node01
root@node01:~# ufw allow from 192.230.202.10 proto tcp to any port 80

# Verify the rule
root@node01:~# ufw status
Status: active

To                         Action    From
--                         ------    ----
22/tcp                     ALLOW     Anywhere
192.230.202.10 80/tcp      ALLOW     Anywhere
22/tcp (v6)                ALLOW     Anywhere (v6)

# Repeat on node02
root@node02:~# ufw allow from 192.230.202.10 proto tcp to any port 80

Configuring the Load Balancer

On the nginx node, create or edit your site configuration:

root@nginx:~# cd /etc/nginx/sites-available/
root@nginx:/etc/nginx/sites-available# vim apache-app

Start with a basic server block:

server {
    listen 80;
    server_name apache.example.com;
    root /var/www/html;

    # Default index files
    index index.html index.htm index.nginx-debian.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

1. Round Robin

Add an upstream block for your backend pool:

# Upstream (Round Robin)
upstream apache_example {
    server 192.230.202.12:80;
    server 192.230.202.3:80;
}

server {
    listen 80;
    server_name apache.example.com;
    root /var/www/html;
    index index.html index.htm index.nginx-debian.html;

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

Enable the site and reload Nginx:

root@nginx:/etc/nginx/sites-available# nginx -t
root@nginx:/etc/nginx/sites-available# ln -s apache-app /etc/nginx/sites-enabled/
root@nginx:/etc/nginx/sites-available# nginx -s reload

Test with curl to see alternating responses:

root@nginx:~# curl localhost
<p>Served by node02</p>
root@nginx:~# curl localhost
<p>Served by node01</p>

2. Weighted Round Robin

Adjust the upstream block to assign server weights:

# Upstream (Weighted Round Robin)
upstream apache_example {
    server 192.230.202.12:80 weight=10;
    server 192.230.202.3:80  weight=1;
}

Reload Nginx to apply:

root@nginx:~# nginx -s reload

Now about 10× more requests go to the higher-weighted server.

3. IP Hash

Enable ip_hash for session stickiness by client IP:

# Upstream (IP Hash)
upstream apache_example {
    ip_hash;
    server 192.230.202.12:80;
    server 192.230.202.3:80;
}

Reload Nginx:

root@nginx:~# nginx -s reload

Consistent Routing

With ip_hash, each client IP always hits the same backend server. This is ideal for stateful applications.


You can extend this setup with health checks, SSL termination, or alternative Nginx modules.

Watch Video

Watch video content

Practice Lab

Practice lab

Previous
Load Balancer