A docker LoadBalancer based on haproxy and inotify
8.3K
A Docker-based HAProxy load balancer with automatic configuration reloading using inotify. This container watches for configuration changes and gracefully reloads HAProxy without downtime, making it ideal for dynamic environments and automated certificate management.
services:
lb:
image: acaranta/lbdocker:latest
environment:
- LBID=mydockerlb
- LOGSPATH=/lblogs
- HASVC=lbdkr.conf
- SYSLOG_SERVER=192.168.0.12
- SYSLOG_PORT=514
- SYSLOG_PROTO=udp
ports:
- 80:80
- 443:443
volumes:
- /pathtovolumes/lbdkr/conf:/hacfg
- /pathtovolumes/lbdkr/log:/lblogs
restart: always
docker run -d \
--name lb \
-e LBID=mydockerlb \
-e LOGSPATH=/lblogs \
-e HASVC=lbdkr.conf \
-p 80:80 \
-p 443:443 \
-v /pathtovolumes/lbdkr/conf:/hacfg \
-v /pathtovolumes/lbdkr/log:/lblogs \
--restart always \
acaranta/lbdocker:latest
| Variable | Required | Default | Description |
|---|---|---|---|
LBID | Yes | - | Unique identifier for your load balancer instance |
HASVC | Yes | hapconf.cfg | Name of your service configuration file (must exist in /hacfg) |
LOGSPATH | No | - | Path inside container where logs will be written |
SYSLOG_SERVER | No | 127.0.0.1 | Remote syslog server address for centralized logging |
SYSLOG_PORT | No | 514 | Syslog server port |
SYSLOG_PROTO | No | udp | Syslog protocol (udp or tcp) |
/hacfg (Required) - Configuration directory containing:
HASVC)certs/ - SSL/TLS certificates (optional, auto-watched)maps/ - HAProxy map files (optional, auto-watched)/lblogs - Log output directory (optional)/pathtovolumes/lbdkr/conf/
├── lbdkr.conf # Your service configuration (HASVC)
├── certs/ # SSL certificates (optional)
│ ├── wildcard.example.com.crt
│ └── importantweb.example.com.crt
└── maps/ # HAProxy maps (optional)
└── domains.map
The service configuration file contains your HAProxy frontends, backends, and other settings. The container provides the global and defaults sections automatically.
# Frontend
frontend front_http
bind :::80 v4v6
mode http
option httplog
default_backend back_web
# Backend
backend back_web
mode http
server web1 webserver.local:80 check
#########################
# Auth #
#########################
userlist AuthUsers
user useradmin insecure-password S3cureP4ss!
#########################
# Frontends definitions #
#########################
frontend front_LB
bind :::80 v4v6
mode http
option httplog
option dontlognull
option forwardfor
# SSL Redirections
redirect scheme https code 301 if { hdr(Host) -i importantweb.example.com } !{ ssl_fc }
# Insecure sites
use_backend back_webassets if { hdr_beg(host) -i assets.example.com }
# Default
default_backend back_default
frontend front_HTTPS
bind :::443 ssl crt /hacfg/certs/wildcard.example.com.crt crt /hacfg/certs/importantweb.example.com.crt accept-proxy v4v6
mode http
option dontlognull
option forwardfor
log-format "%ci:%cp\ [%Tl]\ %ft\ %b/%s\ %[ssl_fc_sni]\ %ST\ %B\ %CC\ %CS\ %tsc\ %sq/%bq\ %hr\ %hs\ %{+Q}r"
use_backend back_importantweb if { ssl_fc_sni importantweb.example.com }
default_backend back_default
#######################
# Backend Definitions #
#######################
backend back_default
mode http
server srv_default mainsrv.mylan.net:80 maxconn 40 check inter 10s fall 4 rise 2
backend back_importantweb
mode http
# Add basic authentication
acl AuthUsers_ACL http_auth(AuthUsers)
http-request auth unless AuthUsers_ACL
server srv_importantweb secureserver.mylan.net:82 maxconn 40 check inter 10s fall 4 rise 2
backend back_webassets
mode http
server srv_webassets mysrvaddress:8080 maxconn 40 check inter 10s fall 4 rise 2
You can configure:
Pre-configured (cannot override):
global section (logging, uid/gid, Lua modules, etc.)defaults section (timeouts, retries, base options)Place certificates in /hacfg/certs/ and reference them in your configuration:
frontend front_HTTPS
bind :::443 ssl crt /hacfg/certs/wildcard.example.com.crt v4v6
...
When certificates are updated (e.g., by Certbot), HAProxy automatically reloads gracefully.
Use maps for dynamic routing without config changes:
/hacfg/maps/domains.map:example.com back_example
api.example.com back_api
frontend front_http
use_backend %[req.hdr(host),lower,map(/hacfg/maps/domains.map,back_default)]
Changes to map files trigger automatic reloads.
HAProxy is compiled with Prometheus exporter support. Add to your configuration:
frontend prometheus
bind *:8404
http-request use-service prometheus-exporter if { path /metrics }
Then scrape metrics from http://container:8404/metrics
Two Lua scripts are included:
These are automatically loaded and available in your configuration.
The container runs an inotify loop that monitors:
HASVC)/hacfg/certs/ directory (if present)/hacfg/maps/ directory (if present)When changes are detected:
/etc/haproxy/haproxy -sf (keeps existing connections alive)The inotify loop checks every 5 seconds and responds immediately to file changes.
# Clone repository
git clone https://github.com/acaranta/lbdocker.git
cd lbdocker
# Build with default HAProxy version (v3.3.0)
docker build -t lbdocker:latest .
# Build with specific HAProxy version
docker build --build-arg HAPROXY_BRANCH=v3.4.0 -t lbdocker:custom .
The build process:
Check your configuration syntax:
docker exec lb haproxy -c -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/lbdkr.conf
Check the inotify loop logs:
docker logs lb
You should see messages like:
Starting inotify loop
Found changes in /hacfg/lbdkr.conf ...
Found changes... gracefully reloading HAProxy
Ensure certificates are in PEM format with the full chain:
cat certificate.crt intermediate.crt root.crt private.key > combined.crt
Add a stats frontend to your configuration:
frontend stats
bind *:8080
stats enable
stats uri /
stats refresh 5s
The container uses these default timeouts (in haproxy.cfg:23-25):
Adjust in your environment or rebuild with custom haproxy.cfg for your use case.
Contributions are welcome! Please:
This project is maintained by Arthur Caranta ([email protected]).
Content type
Image
Digest
sha256:6ea4a2815…
Size
73.4 MB
Last updated
19 days ago
docker pull acaranta/lbdocker