How to configure load balancing for proxy services in Nginx Proxy Manager?
NginxProxyManager (NPM) is a powerful Nginx-based reverse proxy management tool, but configuring server-side load balancing can be a bit troublesome.
Rendering...
NginxProxyManager (NPM), as a powerful Nginx-based reverse proxy management tool, is highly favored by users for its intuitive web interface. While NPM itself is primarily used for managing proxies for single backend services, by cleverly combining it with Nginx's custom configuration capabilities, we can also achieve powerful load balancing functionality.
This article will detail how to configure load balancing for your proxy services by modifying/adding custom configuration files and utilizing the “Custom Nginx Configuration” setting in the NginxProxyManager dashboard. We will focus on this specific approach, without covering other implementation methods.
## 1. Preparation
Before starting the configuration, please ensure you have completed the following preparations:
* **NginxProxyManager is installed and running**: You can install it via Docker or directly.
* **Multiple backend service instances**: You will need at least two or more backend servers providing the same service (e.g., web application instances running on different IPs or ports).
* **NPM data directory access permissions**: You need to be able to access the `/data/nginx/` directory inside the NPM container, typically achieved through Docker volume mounting.
## 2. Core Operations of the Solution
The core idea of this solution is:
1. Create a custom Nginx configuration file in NPM's data directory to define one or more “upstream server groups” (`upstream`).
2. In NPM's proxy host configuration, use the “Custom Nginx Configuration” option to proxy requests to our custom upstream server group.
### 2.1. Creating a Custom Upstream Server Configuration File
First, we need to create a custom file in NPM's Nginx configuration directory to define the load balancing upstream server group.
1. **Access the NPM data directory**:
Typically, NPM's Nginx configuration is located within its Docker container at `/etc/nginx/conf.d/` or `/data/nginx/`. For persistence and easier management, NPM loads custom configurations from the `/data/nginx/custom/` directory.
If you are running NPM with Docker, you can access this directory by mounting a volume. For example, if your NPM container mounts the local `./npm_data` directory to `/data` inside the container, then you should create the file under the `./npm_data/nginx/custom/` path.
2. **Create or modify the configuration file**:
Create a new `.conf` file in the `/data/nginx/custom/` directory, for example, named `http_upstream.conf`.
```bash
# Example: If you are on the host machine and npm_data is the mounted directory
cd /path/to/your/npm_data/nginx/custom/
touch http_upstream.conf
```
3. **Edit the `http_upstream.conf` file**:
Open `http_upstream.conf` with your preferred text editor and add the following content:
```nginx
# Define an upstream server group named 'my_backend_servers'
upstream server_cluster {
# Backend server 1: IP address and port, weight 5
server 192.168.1.100:8080 weight=5 max_fails=3 fail_timeout=30s;
# Backend server 2: IP address and port, weight 3
server 192.168.1.101:8080 weight=3 max_fails=3 fail_timeout=30s;
# Backend server 3: IP address and port, default weight 1
server 192.168.1.102:8080;
# Backup server: Traffic will be forwarded to this server when all primary servers are unavailable
# server 192.168.1.103:8080 backup;
# Marked as unavailable: Typically used for temporary maintenance
# server 192.168.1.104:8080 down;
# Load balancing algorithm (optional, default is round-robin):
# round-robin (default)
# least_conn; # Least connections
# ip_hash; # Hash based on client IP, for session stickiness
# hash $request_uri consistent; # Hash based on URI
}
# If you have other services that require load balancing, you can define more upstream blocks
# upstream server_cluster {
# server 192.168.1.200:9000;
# server 192.168.1.201:9000;
# }
```
**Parameter Explanation**:
* `upstream my_backend_servers { ... }`: Defines an upstream server group named `my_backend_servers`. This name will be used in NPM's custom configuration.
* `server IP:PORT`: Specifies the IP address and port of the backend server.
* `weight=N`: Sets the server's weight. Higher weight means Nginx forwards more requests to it. The default weight is 1.
* `max_fails=N`: Within the `fail_timeout` period, if Nginx fails to communicate with the backend server N times, the server is considered unavailable. The default value is 1.
* `fail_timeout=Ns`: If the number of server failures reaches `max_fails` within N seconds, the server will be marked as unavailable and retried after the `fail_timeout` period. The default value is 10 seconds.
* `backup`: Marks the server as a backup server. Requests are forwarded to a `backup` server only when all non-`backup` servers are unavailable.
* `down`: Marks the server as permanently unavailable. Typically used to temporarily disable a server.
* **Load Balancing Algorithms**:
* `round-robin` (default): Distributes requests to each server in sequence.
* `least_conn`: Sends requests to the server with the fewest current connections.
* `ip_hash`: Distributes requests to servers based on the hash value of the client's IP address, ensuring that requests from the same client are always sent to the same server, achieving session stickiness.
### 2.2. Configuring a Proxy Host in NginxProxyManager
Next, we will create a new proxy host in NPM's web interface and use its “Custom Nginx Configuration” feature to reference our defined upstream server group.
1. **Log in to NginxProxyManager**:
Open your NPM web interface and log in.
2. **Add a new proxy host**:
Navigate to the “Proxy Hosts” page and click “Add Proxy Host”.
3. **Fill in the “Details” tab**:
* **Domain Names**: Enter the domain name you wish to use to access the service via this proxy (e.g., `myapp.example.com`).
* **Scheme**: Select `http` or `https`, depending on the protocol your backend service is listening on.
* **Forward Hostname / IP**: **Fill in a placeholder here, such as `127.0.0.1`.** This setting will not take effect because we will override the actual forwarding target in “Custom Nginx Configuration”, but NPM requires this field to be filled.
* **Forward Port**: **Similarly, fill in a placeholder, such as `80`.**
* Check `Cache Assets`, `Block Common Exploits`, `Websockets Support`, and other options according to your needs.
4. **Configure the “SSL” tab**:
Configure the SSL certificate based on your domain and certificate situation. It is recommended to use Let's Encrypt for automatic application.
5. **Configure “Advanced”**:
This is the most crucial step. In the Advanced tab, find `Custom Nginx Configuration` and enter the following Nginx configuration code in this text box:
```nginx
location / {
proxy_pass http://server_cluster;
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;
}
```
**Explanation**:
* `proxy_pass http://my_backend_servers;`: This directive tells Nginx to forward all requests arriving at this proxy host to the upstream server group named `my_backend_servers`. Nginx will distribute requests according to the load balancing algorithm and server list you defined in `http_upstream.conf`.
* `proxy_set_header ...`: These directives are used to set HTTP request headers, ensuring that backend servers can correctly identify the client's real IP address, original request domain, protocol, and other information. This is crucial for logging, security policies, and the proper functioning of certain applications.
6. **Save the proxy host**:
Click the “Save” button to save your proxy host configuration. NPM will automatically reload the Nginx configuration for the changes to take effect.
### 2.3. Verifying Load Balancing Configuration
After the configuration is complete, you need to verify that load balancing is working correctly.
1. **Access your domain**:
Access your configured domain in a browser (e.g., `http://myapp.example.com` or `https://myapp.example.com`).
2. **Check backend server response**:
If your backend service can display its server's identifier (e.g., server IP, hostname, or unique page content), you can refresh the page multiple times to observe if requests are distributed to different backend servers.
3. **Check NginxProxyManager logs**:
Check NPM's logs to confirm there are no configuration errors.
4. **Backend server logs**:
Check the access logs of the backend servers to confirm that requests are indeed coming from NPM and are being distributed to different servers.
## 4. Summary and Notes
By following the steps above, you have successfully configured load balancing for your proxy services in NginxProxyManager. This method fully leverages the convenience of NPM's management interface and the flexibility of Nginx's underlying configuration.
**Notes**:
* **Session Stickiness**: If your application requires user sessions to maintain connections with a specific backend server (e.g., a user must access the same server after logging in), you might need to use the `ip_hash` load balancing algorithm, or implement session sharing at the application level (e.g., using Redis).
* **Health Checks**: Nginx's `max_fails` and `fail_timeout` provide basic health check functionalities. For more advanced health checks (e.g., checking the response content of a specific URL), you might need to combine other tools or more complex Nginx configurations.
* **Configuration Updates**: When you modify the `http_upstream.conf` file, NPM does not automatically reload the Nginx configuration. You need to go into NPM's web interface, find any proxy host, edit and save it (without making any actual changes), and NPM will then reload all Nginx configurations. Alternatively, if you are directly operating Docker, you can restart the NPM container.
> Do you have any other solutions?Comments
Please login to view and post comments
Go to Login