This guide provides instructions for running HAProxy in Docker containers with production-ready configurations.
For Docker installation, see Docker.
Create a directory to store your configuration and compose files.
mkdir -p /opt/haproxy/config
cd /opt/haproxy
Create a basic HAProxy configuration file:
# /opt/haproxy/config/haproxy.cfg
global
log stdout local0
maxconn 4000
user haproxy
group haproxy
stats socket /var/run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
defaults
mode http
log global
option httplog
option dontlognull
option forwardfor
option http-server-close
timeout connect 5s
timeout client 50s
timeout server 50s
retries 3
option redispatch
frontend http_front
bind *:80
mode http
default_backend http_back
backend http_back
balance random(2)
server server1 web1:80 check
server server2 web2:80 check
Define a container for HAProxy with proper configuration:
version: '3.8'
services:
haproxy:
image: haproxy:3.3
container_name: haproxy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "8404:8404" # Stats port
volumes:
- ./config:/usr/local/etc/haproxy:ro
- haproxy-run:/var/run/haproxy
networks:
- haproxy-network
depends_on:
- web1
- web2
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
web1:
image: nginx:alpine
container_name: web1
restart: unless-stopped
networks:
- haproxy-network
web2:
image: nginx:alpine
container_name: web2
restart: unless-stopped
networks:
- haproxy-network
networks:
haproxy-network:
driver: bridge
volumes:
haproxy-run:
For production use with SSL termination:
version: '3.8'
services:
haproxy:
image: haproxy:3.3
container_name: haproxy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "8404:8404" # Stats port (restrict access in production!)
volumes:
- ./config:/usr/local/etc/haproxy:ro
- ./certs:/usr/local/etc/haproxy/certs:ro
- haproxy-run:/var/run/haproxy
networks:
- haproxy-network
depends_on:
- web1
- web2
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
environment:
- TZ=Etc/UTC
web1:
image: nginx:alpine
container_name: web1
restart: unless-stopped
networks:
- haproxy-network
volumes:
- ./html:/usr/share/nginx/html:ro
web2:
image: nginx:alpine
container_name: web2
restart: unless-stopped
networks:
- haproxy-network
volumes:
- ./html:/usr/share/nginx/html:ro
networks:
haproxy-network:
driver: bridge
volumes:
haproxy-run:
# /opt/haproxy/config/haproxy.cfg for SSL
global
log stdout local0
maxconn 4000
user haproxy
group haproxy
stats socket /var/run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
defaults
mode http
log global
option httplog
option dontlognull
option forwardfor
option http-server-close
timeout connect 5s
timeout client 50s
timeout server 50s
retries 3
option redispatch
frontend http_front
bind *:80
mode http
http-request redirect scheme https code 301 if !{ ssl_fc }
frontend https_front
bind *:443 ssl crt /usr/local/etc/haproxy/certs/cert.pem
mode http
default_backend http_back
backend http_back
balance random(2)
server server1 web1:80 check
server server2 web2:80 check
listen stats
bind *:8404
mode http
stats enable
stats uri /
stats refresh 30s
# IMPORTANT: Restrict access in production!
# acl local_access src 172.16.0.0/12 192.168.0.0/16
# http-request deny unless local_access
Start the containers in the background:
# For basic setup
docker compose up -d
# Check the status
docker compose ps
# View logs
docker compose logs -f haproxy
# Restart HAProxy container
docker compose restart haproxy
# Update configuration (after editing haproxy.cfg)
docker compose exec haproxy haproxy -c -f /usr/local/etc/haproxy/haproxy.cfg
docker compose restart haproxy
# Enter the container for debugging
docker exec -it haproxy /bin/sh
latestCommon issues and solutions:
haproxy -c -f /path/to/configRunning containers in production? We help with:
Need help? office@linux-server-admin.com or Contact Us