Configure Apache reverse proxy and load balancing for high availability

Intermediate 45 min Apr 26, 2026 507 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Set up Apache as a reverse proxy with load balancing across multiple backend servers. Configure health checks, SSL termination, and failover for production high availability deployments.

Prerequisites

  • Root or sudo access
  • Multiple backend servers for testing
  • Basic understanding of HTTP and networking

What this solves

Apache reverse proxy with load balancing distributes incoming requests across multiple backend servers, improving performance and availability. This configuration provides SSL termination, health monitoring, and automatic failover when backend servers become unavailable.

Step-by-step configuration

Update system packages

Start by updating your package manager to ensure you get the latest versions of Apache and required modules.

sudo apt update && sudo apt upgrade -y
sudo dnf update -y

Install Apache HTTP server

Install Apache web server which will act as the reverse proxy and load balancer for your backend applications.

sudo apt install -y apache2
sudo dnf install -y httpd

Enable required Apache modules

Enable the proxy, proxy_http, proxy_balancer, lbmethod_byrequests, and headers modules for reverse proxy functionality and load balancing.

sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_balancer
sudo a2enmod lbmethod_byrequests
sudo a2enmod headers
sudo a2enmod ssl
sudo sed -i 's/#LoadModule proxy_module/LoadModule proxy_module/' /etc/httpd/conf.modules.d/00-proxy.conf
sudo sed -i 's/#LoadModule proxy_http_module/LoadModule proxy_http_module/' /etc/httpd/conf.modules.d/00-proxy.conf
sudo sed -i 's/#LoadModule proxy_balancer_module/LoadModule proxy_balancer_module/' /etc/httpd/conf.modules.d/00-proxy.conf
sudo sed -i 's/#LoadModule lbmethod_byrequests_module/LoadModule lbmethod_byrequests_module/' /etc/httpd/conf.modules.d/00-proxy.conf
sudo sed -i 's/#LoadModule ssl_module/LoadModule ssl_module/' /etc/httpd/conf.modules.d/00-ssl.conf

Create SSL certificates

Generate self-signed SSL certificates for testing, or place your purchased certificates in the Apache SSL directory.

sudo mkdir -p /etc/ssl/private
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/ssl/private/apache-selfsigned.key \
  -out /etc/ssl/certs/apache-selfsigned.crt \
  -subj "/C=US/ST=State/L=City/O=Organization/CN=example.com"
sudo mkdir -p /etc/pki/tls/private
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/pki/tls/private/apache-selfsigned.key \
  -out /etc/pki/tls/certs/apache-selfsigned.crt \
  -subj "/C=US/ST=State/L=City/O=Organization/CN=example.com"

Configure reverse proxy with load balancing

Create the main configuration file that defines the backend server pool and load balancing rules with health checks.





Configure advanced load balancing options

Create a separate configuration file for advanced load balancing features including sticky sessions and failover settings.

# Advanced load balancer configuration

# Enable mod_status for monitoring


# Proxy timeout settings
ProxyTimeout 300
ProxyPreserveHost On

# Connection pooling
ProxyIOBufferSize 65536

# Proxy pass settings for different application contexts




# Define API backend cluster


# Define static content cluster  
# Advanced load balancer configuration

# Enable mod_status for monitoring


# Proxy timeout settings
ProxyTimeout 300
ProxyPreserveHost On

# Connection pooling
ProxyIOBufferSize 65536

# Proxy pass settings for different application contexts




# Define API backend cluster


# Define static content cluster  

Enable the site configuration

Enable the load balancer site and disable the default Apache site to prevent conflicts.

sudo a2ensite loadbalancer.conf
sudo a2enconf balancer-advanced.conf
sudo a2dissite 000-default
sudo a2enmod rewrite
sudo a2enmod expires
# Configuration files are automatically loaded from conf.d/
# Enable rewrite module
echo "LoadModule rewrite_module modules/mod_rewrite.so" | sudo tee -a /etc/httpd/conf.modules.d/00-base.conf
echo "LoadModule expires_module modules/mod_expires.so" | sudo tee -a /etc/httpd/conf.modules.d/00-base.conf

Configure firewall rules

Open the necessary ports for HTTP, HTTPS, and management access while securing the balancer manager interface.

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow from 10.0.0.0/8 to any port 80
sudo ufw allow from 172.16.0.0/12 to any port 80
sudo ufw allow from 192.168.0.0/16 to any port 80
sudo ufw --force enable
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" service name="http" accept'
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="172.16.0.0/12" service name="http" accept'
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.0.0/16" service name="http" accept'
sudo firewall-cmd --reload

Test configuration and start Apache

Validate the Apache configuration syntax and start the service with the new load balancer settings.

sudo apache2ctl configtest
sudo systemctl enable apache2
sudo systemctl restart apache2
sudo systemctl status apache2
sudo httpd -t
sudo systemctl enable httpd
sudo systemctl restart httpd
sudo systemctl status httpd

Configure health check monitoring

Set up a monitoring script that checks the load balancer status and backend health automatically.

#!/bin/bash

# Load balancer health check script
LOG_FILE="/var/log/loadbalancer-health.log"
EMAIL="admin@example.com"
BALANCER_URL="http://localhost/balancer-manager"

# Function to log messages
log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
}

# Check Apache service status
if ! systemctl is-active --quiet apache2 httpd 2>/dev/null; then
    log_message "ERROR: Apache service is not running"
    echo "Apache load balancer is down on $(hostname)" | mail -s "Load Balancer Alert" "$EMAIL"
    exit 1
fi

# Check if balancer manager is accessible
if ! curl -s "$BALANCER_URL" > /dev/null; then
    log_message "WARNING: Balancer manager not accessible"
fi

# Check backend server connectivity
BACKENDS=("http://203.0.113.10:8080/health" "http://203.0.113.11:8080/health" "http://203.0.113.12:8080/health")
FAILED_BACKENDS=()

for backend in "${BACKENDS[@]}"; do
    if ! curl -s -f "$backend" -m 10 > /dev/null; then
        FAILED_BACKENDS+=("$backend")
        log_message "ERROR: Backend $backend is not responding"
    fi
done

# Alert if more than half of backends are down
if [ ${#FAILED_BACKENDS[@]} -gt $((${#BACKENDS[@]} / 2)) ]; then
    log_message "CRITICAL: More than half of backend servers are down"
    echo "Critical: Multiple backend servers down on $(hostname): ${FAILED_BACKENDS[*]}" | mail -s "Load Balancer Critical Alert" "$EMAIL"
fi

log_message "Health check completed - Active backends: $((${#BACKENDS[@]} - ${#FAILED_BACKENDS[@]}))/${#BACKENDS[@]}"
exit 0

Set up automated monitoring

Create a systemd timer to run the health check script every 5 minutes and make it executable.

sudo chmod +x /usr/local/bin/check-loadbalancer.sh
sudo chown root:root /usr/local/bin/check-loadbalancer.sh
[Unit]
Description=Load Balancer Health Check
After=network.target

[Service]
Type=oneshot
User=root
ExecStart=/usr/local/bin/check-loadbalancer.sh
StandardOutput=journal
StandardError=journal
[Unit]
Description=Run Load Balancer Health Check every 5 minutes
Requires=loadbalancer-health.service

[Timer]
OnBootSec=5min
OnUnitActiveSec=5min
AccuracySec=1s

[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable loadbalancer-health.timer
sudo systemctl start loadbalancer-health.timer

Verify your setup

Test the load balancer configuration and verify that requests are being distributed across backend servers.

# Check Apache configuration
sudo apache2ctl configtest

# Verify Apache is running and listening on correct ports
sudo systemctl status apache2
sudo netstat -tlnp | grep :80
sudo netstat -tlnp | grep :443

# Test HTTP to HTTPS redirect
curl -I http://example.com

# Test HTTPS load balancing
curl -k -I https://example.com

# Check balancer manager (replace with your server IP)
curl http://127.0.0.1/balancer-manager

Automated install script

Run this to automate the entire setup

Don't want to manage this yourself?

We handle infrastructure for businesses that depend on uptime. Fully managed, with one fixed contact who knows your setup.

You get one fixed contact who knows your setup

Rotterdam 01:24 · reachable in a message, no ticket form