Skip to main content

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 https://mintcdn.com/thedailyprothomalo/BHFxhJnL0YxSMxN8/icons/haproxy.svg?fit=max&auto=format&n=BHFxhJnL0YxSMxN8&q=85&s=65943fc99ceb792b9b02a9d35d19e1c5HAProxy, 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:
cd /opt/haproxy/
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:
docker ps
You should see both haproxy and certbot containers listed as running.

Step 5: Access HAProxy Stats Dashboard

  1. Open your web browser and navigate to http://your-server-ip:8080/stats.
  2. 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.