Community Knowledge Base

Deploying NGINX as a Load Balancer

This page provides a simple walkthrough for deploying NGINX as a load balancer in front of two or more back end servers. The steps include installing NGINX, configuring upstream servers, enabling proxy headers, and verifying the configuration. For the sake of this document, we'll be using Ubuntu, but other Linux distros can also be used.

Preparing Your Load Balancer Host

Before configuring NGINX, ensure you have the following:

  • An Ubuntu Server machine to act as your load balancer
  • Two or more backend servers running the SmarterMail
  • Network connectivity from the load balancer to each backend
  • Static IP addresses set for all involved hosts

Installing NGINX on Ubuntu

Installing NGINX on Ubuntu is a relatively simple process:

First, update your packages

sudo apt update

Next, install NGINX

sudo apt install -y nginx

Next, enable and start the service

sudo systemctl enable nginx
sudo systemctl start nginx

Allow HTTP/HTTPS in Uncomplicated Firewall (UFW)

sudo ufw allow 'Nginx Full'

Finally, confirm the installation

Go to the load balancer's IP address in a web browser to verify it's running: https://load-balancer-IP/. Ideally, you'll see the default Welcome to NGINX page. This lets you know that NGINX is properly installed and ready for the next step: Configuration.

Configuring NGINX for Load Balancing

All load balancing configuration files will be placed in one of two places. Either withing a standalone load-balancer.conf file (/etc/nginx/conf.d/load-balancer.conf) or inside the http {} block of the nginx.conf file (/etc/nginx/nginx.conf). For the sake of our example, we'll use the nginx.conf file configuration.

Add the upstream and proxy configuration

Inside nginx.conf, replace the default back end IPs with your own server addresses:

http {
   #Define back end servers, replacing default-ip-address with your own
upstream backend {
server default-ip-address1;
server default-ip-address2;
#Add more back ends as needed
}
   #Front end server block server {
listen 80;
server_name;    #catch-all
location / {
proxy_pass http://backend;
   #Recommended proxy headers
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;
}
}
}

Be sure to Save the nginx.conf file before exiting.

Load Balancing SMTP with NGINX

NGINX can load balance SMTP traffic (as well as IMAP/POP3 and any TCP-based service) using the stream context/module. This is separate from the HTTP configuration and is placed outside the http {} block in its own stream {} block.

This is useful if your backend servers provide SMTP services and you want to distribute client load across them.

Create the SMTP Load Balancer Configuration

First, create a new config file for stream traffic.

sudo nano /etc/nginx/conf.d/smtp-lb.conf

Next, add the following:

stream {
   # Define your SMTP backend servers
upstream smtp_backend {
   # Default: round-robin distribution
server default-ip-address1;
server default-ip-address2;
   # Add more backends as needed
}

   # Expose port 25 on the load balancer
server {
listen 25;
proxy_pass smtp_backend;

   # Optional: Preserve client IP for servers that support PROXY protocol
   # proxy_protocol on;

   # Optional timeout tuning
proxy_timeout 300s;
proxy_connect_timeout 5s;
}
}

Be sure to Save the smtp-lb.conf file before exiting.

Notes on SMTP Load Balancing

SMTP is not HTTP, so:

  • You MUST use the stream module
  • No HTTP directives (e.g., proxy_set_header) are allowed
  • It operates at Layer 4 (TCP)

Testing and Reloading the Configuration

It's important to always validate the configuration before reloading:

# Test NGINX syntax
sudo nginx -t

# Reload NGINX
sudo systemctl reload nginx

If no errors appear, NGINX is now actively load-balancing requests across the back end servers.

Optional Load Balancing Modes

NGINX supports several advanced balancing strategies. Add these inside the upstream backend {} block of your nginx.conf file.

Least Connections

This balances traffic across the least busy node.

least_conn;

IP Hash (Session Persistence)

Ensures a client always hits the same back end once the initial connection is established.

ip_hash;

Weighted Servers

Allocates more traffic to a more powerful server.

server ip_address1 weight=5;
server ip_address2 weight=1;

Backup or Temporarily Disable Nodes

server ip_address1 backup;
server ip_address2 down;

Validate Load Balancing Functionality

To confirm everything is working, do the following:

  1. Access the site via the load balancer IP or domain
  2. Refresh several times
  3. Confirm that the responses come from different back end nodes

If you see alternating responses, the load balancer is functioning correctly. If not, check the NGINX logs:

  • /var/log/nginx/error.log
  • /var/log/nginx/access.log