NGINX.COM
Web Server Load Balancing with NGINX Plus

This is a guest blog post by Nitish Tiwari, a software developer for Minio, a distributed object storage server specialized for cloud applications and the DevOps approach to app development and delivery. Nitish’s interests include software‑based infrastructure, especially storage and distributed systems.

In this post, Nitish explains how to use NGINX and NGINX Plus as a reverse proxy and load balancer for Minio servers. The post applies equally to NGINX and NGINX Plus; for brevity it refers to NGINX Plus only.

Designing Object Storage

Almost all applications need storage, but different apps need and use storage in particular ways. Take for example, a document store: it might not need to serve frequent read requests when small, but needs to scale as time progresses. Another application, such as an image gallery, needs to both satisfy requests quickly and scale with time.

These nuances make storage setup tough. However, everything is not gloomy – with the advent of object storage as the default way to store unstructured data, HTTP has become the default communication mode, standardizing how applications communicate with storage.

Still, the question remains: How do you build an object storage setup that is tailored for your application requirements, but still flexible?

Because object storage involves HTTP servers and clients, it makes sense to have a versatile web server like NGINX Plus in front to handle HTTP traffic. A lightweight object storage server such as Minio can be used to provide scalable storage at the backend. The flexibility of such a system is the key to creating an enterprise‑grade service.

NGINX Plus is an effective load balancer for distributed instances of the Minio cloud-based object storage server
NGINX Plus terminates SSL/TLS client connections and load balances Minio cloud storage servers

With NGINX Plus, administrators can not only load balance incoming traffic – they can cache, throttle, terminate SSL/TLS, and even filter the traffic based on various parameters. Minio, on the other hand, offers a lightweight object storage server that is compatible with Amazon S3.

Minio is best suited for storing unstructured data such as photos, videos, log files, backups, and VM and container images. Minio server is light enough to be bundled with the application stack, similar to Node.js, Redis, and MySQL. Minio also supports a distributed mode, letting you pool multiple drives – even on different machines – into a single object storage server.

In this post we’ll explore some of the features of NGINX Plus in various use cases and learn how to combine them with Minio to set up a production‑grade, highly scalable, highly available, and stable object storage system.

NGINX Plus as a Reverse Proxy and Load Balancer

NGINX Plus is well known as a reverse proxy server. But why does one need a reverse proxy for Minio? Let’s look at some of the use cases:

  • With an NGINX Plus reverse proxy in front of one or more Minio servers, you have the freedom to move Minio server instances to different machines/locations over time, without having to update clients or applications.
  • NGINX Plus can load balance incoming traffic and spread it evenly across distributed Minio server instances.
  • An NGINX Plus proxy can be part of a highly available object storage setup with Minio, using the Minio Client (mc) mirror command.

NGINX Plus reverse proxies client traffic by passing requests to a backend server, which is listening on the URL specified by the proxy_pass directive. In the following configuration snippet, a standalone Minio instance is running on localhost, so it’s available at http://localhost:9000. All requests coming on port 80 to the top‑level directory (/) at www.example.com are passed to Minio. NGINX Plus explicitly sets the Host header to its value in the original request.

server {
    listen 80;
    server_name www.example.com;

    location / {
        proxy_set_header Host $http_host;
        proxy_pass       http://localhost:9000;
    }
}

If you have multiple Minio servers, load balance traffic among them by listing them in an upstream configuration block and referencing the upstream group in the proxy_pass directive:

upstream minio_servers {
    server minio-server-1:9000;
    server minio-server-2:9000;
}

server {
    listen 80;
    server_name www.example.com;

    location / {
        proxy_set_header Host $http_host;
        proxy_pass       http://minio_servers;
    }
}

For more details about setting up NGINX or NGINX Plus as a proxy for Minio, see the Minio documentation.

SSL/TLS Termination

With HTTPS now becoming the default protocol for much web traffic, it makes sense to deploy an HTTPS server, rather than simply an HTTP server, for Minio. It’s fairly easy to set up NGINX Plus as an HTTPS server. You need a SSL/TLS certificate to get started; Let’s Encrypt provides free SSL/TLS certificates and integrates with NGINX Plus.

The next step is to edit the NGINX Plus configuration file. Here you need to specify the ssl parameter to the listen directive in the server block, then specify the files containing the server certificate and private key:

server {
    listen 80;
    server_name www.example.com;
    return 301 https://www.example.com$request_uri;
}

server {
    listen              443 ssl;
    server_name         www.example.com;

    ssl_certificate     www.example.com.crt;
    ssl_certificate_key www.example.com.key;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;

    location / {
        proxy_set_header Host $http_host;
        proxy_pass       http://localhost:9000;
    }
}

For more information about SSL/TLS termination, see the NGINX Plus Admin Guide.

Caching

Object storage servers are not known for their speed, but that doesn’t have to mean slow responses to clients. When you enable caching on the NGINX Plus server, it saves frequently accessed data which it can return to the client immediately without having to forward the request to the backend server.

Here is how it works. The NGINX Plus web cache sits in between a client and Minio, saving a copy of each requested content file. When a client requests content that is stored in the cache, NGINX Plus returns it directly, without contacting Minio. This both improves response time to the client and reduces the load on the Minio server.

You set up the NGINX Plus cache for Minio with the proxy_cache_path and proxy_cache directives. The proxy_cache_path directive sets the location and configuration of the cache, and the proxy_cache directive activates it. For details, see A Guide to Caching with NGINX and NGINX Plus.

proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m 
                 use_temp_path=off;

server {
    # ...
    location / {
        proxy_cache      my_cache;
        proxy_set_header Host $http_host;
        proxy_pass       http://localhost:9000;
    }
}

Throttling

Sometimes you need to throttle requests for business or security reasons. With NGINX Plus, you can limit the available bandwidth, number of requests, or number of connections.

To throttle bandwidth, use the limit_rate directive. This example limits download speed to 200 KB per second:

server {
    # ...
    location /images/ {
        limit_rate 200k;
        # ...
    }
}

For request throttling, use the limit_req and limit_req_zone directives, as in this example which limits each unique IP address to 10 requests per second while allowing for bursts of 20 requests.

limit_req_zone $binary_remote_addr zone=my_req_limit:10m rate=10r/s;

server {
    # ...
    location /images/ {
        limit_req zone=my_req_limit burst=20;
        # ...
    }
}

To throttle the number of connections, use the limit_conn and limit_conn_zone directives. This example limits each unique IP address to 5 simultaneous connections.

limit_conn_zone $binary_remote_addr zone=my_conn_limit:10m;

server {
    # ...
    location /images/ {
        limit_conn my_conn_limit 5;
        # ...
    }
}

For more details, see the NGINX Plus Admin Guide.

Summary

In this post we demonstrated the use of several NGINX Plus features for load balancing in – particular, for load balancing in front of a Minio object storage server. The combination of NGINX Plus and Minio allows you to set up a flexible object storage server tailored for your application requirements.

For more on load balancing with NGINX Plus, see these blog posts and other resources:

To try NGINX Plus for yourself, start your free 30-day trial today or contact us to discuss your use cases.

Hero image
Free O'Reilly eBook: The Complete NGINX Cookbook

Updated for 2024 – Your guide to everything NGINX



About The Author

Nitish Tiwari

About F5 NGINX

F5, Inc. is the company behind NGINX, the popular open source project. We offer a suite of technologies for developing and delivering modern applications. Together with F5, our combined solution bridges the gap between NetOps and DevOps, with multi-cloud application services that span from code to customer.

Learn more at nginx.com or join the conversation by following @nginx on Twitter.