Documentation Index
Fetch the complete documentation index at: https://docs.riad.com.bd/llms.txt
Use this file to discover all available pages before exploring further.
Introduction
In this guide, we will walk through the steps to deploy
HAProxy, a reliable and high-performance open-source load balancer and reverse proxy, within a Docker container. We will also configure automated SSL certificate management using Let’s Encrypt to ensure secure HTTPS connections.
HAProxy and Let’s Encrypt:
HAProxy is widely used in production environments for its robustness, scalability, and advanced load balancing capabilities. It efficiently distributes incoming traffic across multiple backend servers, enhancing application performance and reliability.
Let’s Encrypt is a free, automated, and open certificate authority that provides SSL/TLS certificates to enable HTTPS on websites. By integrating Let’s Encrypt with HAProxy, we can automate the process of obtaining and renewing SSL certificates, ensuring that our applications remain secure without manual intervention.
Overview of the Deployment:
In this deployment, we will set up HAProxy as a reverse proxy in a Docker container. HAProxy will handle incoming HTTPS requests, route them to the appropriate backend services, and manage SSL certificates using Let’s Encrypt. The deployment will include the following key components:
- HAProxy Docker Container: The core component that will run HAProxy and manage traffic routing.
- Let’s Encrypt Integration: Automated SSL certificate issuance and renewal using the ACME protocol.
- Backend Services: The applications or services that HAProxy will route traffic to.
Prerequisites
Before we begin, ensure you have the following prerequisites in place:
- A server or virtual machine with Docker installed.
- A domain name pointing to your server’s IP address.
- Basic knowledge of Docker and HAProxy.
Logical Diagram
+-------------------+ +------------------+
| | | |
| Client Browser +--------->| HAProxy |
| | | Reverse Proxy |
+-------------------+ +--------+---------+
|
|
+--------v---------+
| |
| Backend Apps |
| |
+------------------+
Directory Structure
Before we start, let’s outline the directory structure we will use for this deployment:
/opt/haproxy/
├── docker-haproxy.yml
├── haproxy.cfg
└── certbot-init.sh
Step 1: Create HAProxy Configuration File
a. Create a file named haproxy.cfg in the /opt/haproxy/ directory with the following content:
# =====================
# Global Settings
# =====================
global
# Log to stdout in raw format using local0 facility
log stdout format raw local0
# Run as a daemon in background
daemon
# Maximum concurrent connections
maxconn 2000
# Default DH parameter size for SSL (affects Perfect Forward Secrecy)
tune.ssl.default-dh-param 2048
# SSL cipher suites - only HIGH strength, exclude anonymous and MD5
ssl-default-bind-ciphers HIGH:!aNULL:!MD5
# Disable insecure SSL/TLS versions
ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11
# =====================
# Defaults
# =====================
defaults
# Inherit logging settings from global section
log global
# Default mode (HTTP vs TCP)
mode http
# Don't log connections with no data
option dontlognull
# Number of retries on failure
retries 3
# Timeout for connection to server
timeout connect 5s
# Timeout for client inactivity
timeout client 50s
# Timeout for server inactivity
timeout server 50s
# Custom log format with timing, connection info, and request details
log-format "%t %ci:%cp [%TR] %ft %b/%s %ST %B \"%r\""
# =====================
# Frontend: HTTP (Redirect to HTTPS)
# =====================
frontend http_front
# Listen on all interfaces port 80
bind *:80
mode http
# Permanent redirect (301) all HTTP traffic to HTTPS
redirect scheme https code 301 if !{ ssl_fc }
# =====================
# Frontend: HTTPS
# =====================
frontend https_front
# Listen on all interfaces port 443 with SSL certificate
# Supports HTTP/2 and HTTP/1.1 via ALPN negotiation
bind *:443 ssl crt /opt/haproxy/certs/live/ha.riad.com.bd/haproxy.pem alpn h2,http/1.1
mode http
# Add X-Forwarded-For header with client IP
option forwardfor
# Set X-Forwarded-Proto header to help backend apps detect HTTPS
http-request set-header X-Forwarded-Proto https if { ssl_fc }
# Enable HSTS (HTTP Strict Transport Security) for security
http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains" if { ssl_fc }
# Send traffic to the backend server group
default_backend iis_servers
# =====================
# Backend: IIS servers
# =====================
backend iis_servers
mode http
# Load balancing algorithm - distribute requests evenly
balance roundrobin
# Health check method - GET request to root
option httpchk GET /
# Allow redispatch to another server if one fails
option redispatch
# Health check timeout
timeout check 5s
# Enable cookie-based session persistence
# SRV cookie is inserted by HAProxy, indirect mode, no cache
cookie SRV insert indirect nocache
# Define IIS servers with cookie settings
# Each server gets a unique cookie for session persistence
server iis01 192.168.9.45:80 check cookie iis01
server iis02 192.168.9.46:80 check cookie iis02
# =====================
# HAProxy Stats
# =====================
listen stats
# Listen on port 8080 for statistics
bind *:8080
# Enable statistics page
stats enable
# Statistics page URI
stats uri /stats
# Auto-refresh stats every 10 seconds
stats refresh 10s
# Authentication for stats page (username:admin, password:XXXXXXXX)
stats auth admin:XXXXXXXX
b. Save and close the file.
Step 2: Create Docker Compose File
a. Create a file named docker-haproxy.yml in the /opt/haproxy/ directory with the following content:
services:
haproxy:
image: haproxy:lts-alpine # Use lightweight Alpine-based HAProxy image
container_name: haproxy # Explicit container name for easy reference
restart: unless-stopped # Automatically restart unless manually stopped
ports:
- "80:80" # HTTP traffic
- "443:443" # HTTPS traffic
- "8080:8080" # HAProxy stats dashboard for monitoring
environment:
- TZ=Asia/Dhaka # Set timezone for proper logging
volumes:
- ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro # Mount custom config
- ./certs:/opt/haproxy/certs:ro # SSL certificates directory
- /etc/localtime:/etc/localtime:ro # Sync host time
networks:
- haproxy-net # Connect to custom network
certbot:
image: certbot/certbot:latest # Official Certbot image for SSL certificates
container_name: certbot
restart: unless-stopped
volumes:
- ./certs:/etc/letsencrypt # Persist Let's Encrypt certificates
- ./certs:/opt/haproxy/certs # Share certificates with HAProxy
entrypoint: >
/bin/sh -c '
trap exit TERM; # Handle graceful shutdown
# Initial certificate obtain
certbot certonly --standalone -d ha.riad.com.bd --non-interactive --agree-tos -m riadreza41@gmail.com;
# Combine private key and certificate for HAProxy
cat /etc/letsencrypt/live/ha.riad.com.bd/privkey.pem /etc/letsencrypt/live/ha.riad.com.bd/fullchain.pem > /opt/haproxy/certs/live/ha.riad.com.bd/haproxy.pem;
# Set proper permissions
chmod 644 /opt/haproxy/certs/live/ha.riad.com.bd/haproxy.pem;
# Loop to auto-renew every 12 hours
while :; do
sleep 12h & wait $${!};
# Renew certificates
certbot renew --deploy-hook "cat /etc/letsencrypt/live/ha.riad.com.bd/privkey.pem /etc/letsencrypt/live/ha.riad.com.bd/fullchain.pem > /opt/haproxy/certs/live/ha.riad.com.bd/haproxy.pem && chmod 644 /opt/haproxy/certs/live/ha.riad.com.bd/haproxy.pem && docker kill -s HUP haproxy";
# --deploy-hook: After renewal, rebuild HAProxy cert and reload config
done
'
networks:
- haproxy-net
networks:
haproxy-net:
external: true # Use pre-existing external network
b. Save and close the file.
Step 3: Create Certificates Directory
a. Create a directory named certs in the /opt/haproxy/ directory to store SSL certificates:
mkdir -p /opt/haproxy/certs/live/ha.riad.com.bd
Step 4: Deploy HAProxy and Certbot Containers
a. Navigate to the /opt/haproxy/ directory:
b. Start the HAProxy and Certbot containers using Docker Compose:
docker-compose -f docker-haproxy.yml up -d
c. Verify that the containers are running:
You should see both haproxy and certbot containers listed as running.
Step 5: Access HAProxy Stats Dashboard
- Open your web browser and navigate to
http://your-server-ip:8080/stats.
- You should see the HAProxy statistics dashboard. Log in using the credentials specified in the
haproxy.cfg file (username: admin, password: XXXXXXXX).
Conclusion
You have successfully deployed HAProxy in a Docker container with automated SSL certificate management using Let’s Encrypt. HAProxy is now set up to handle incoming HTTPS requests, route them to your backend services, and automatically renew SSL certificates as needed. You can monitor HAProxy’s performance and traffic through the stats dashboard.