No description
| haproxy_health | ||
| .gitignore | ||
| .python-version | ||
| justfile | ||
| pyproject.toml | ||
| README.md | ||
| uv.lock | ||
HAProxy Health Check API
Health check API for HAProxy frontends and backends, designed for integration with keepalived/IPVS load balancers. Monitors HAProxy stats socket and exposes HTTP health endpoints on port 9300.
Features
- Frontend and backend health checks via HTTP API
- HAProxy stats socket integration
- Dual-stack IPv4/IPv6 support
- JSON and plain text responses
- Configurable via CLI args or environment variables
Installation
Requires Python 3.11+ and uv:
# Install uv if needed
curl -LsSf https://astral.sh/uv/install.sh | env UV_INSTALL_DIR=/usr/local/bin sh
# Install from git
uv pip install git+https://nrtn.dev/catalyst/haproxy-health.git
# Or run without installing (recommended for systemd)
uv run --with haproxy-health@git+https://nrtn.dev/catalyst/haproxy-health.git haproxy-health
Configuration
# CLI options
haproxy-health --port 9300 --host "*" --threads 4
# Or use environment variables
export HAPROXY_HEALTH_PORT=9300
export HAPROXY_HEALTH_HOST="*" # "*" (all), "0.0.0.0" (IPv4), "::" (IPv6)
export HAPROXY_HEALTH_THREADS=4
API Endpoints
# Frontend health check (returns 200/503)
curl http://localhost:9300/health?frontend=http_front
curl http://localhost:9300/health?frontend=https_front
# Backend health check (returns 200/503)
curl http://localhost:9300/health?backend=http_backend
# With JSON summary
curl http://localhost:9300/health?frontend=http_front&summary=true
# Status overview (all frontends/backends)
curl http://localhost:9300/status
Systemd Integration
Create /etc/systemd/system/haproxy-health.service:
[Unit]
Description=HAProxy Health Check API
After=haproxy.service
Requires=haproxy.service
[Service]
Type=simple
ExecStart=/usr/local/bin/uv run --with haproxy-health@git+https://nrtn.dev/catalyst/haproxy-health.git haproxy-health
Restart=always
RestartSec=5
User=haproxy
Group=haproxy
Environment="UV_CACHE_DIR=/var/cache/uv"
Environment="HAPROXY_HEALTH_PORT=9300"
[Install]
WantedBy=multi-user.target
Enable and start:
sudo mkdir -p /var/cache/uv && sudo chown haproxy:haproxy /var/cache/uv
sudo systemctl daemon-reload
sudo systemctl enable --now haproxy-health.service
# Update to latest version
sudo rm -rf /var/cache/uv/* && sudo systemctl restart haproxy-health.service
How It Works
Keepalived → HTTP GET /health?frontend=http_front (port 9300)
↓
Health Check API → Query HAProxy stats socket
↓
HAProxy Stats → Parse backend server status
↓
Return 200 (healthy) or 503 (unhealthy)
Development
# Clone and run locally
git clone https://nrtn.dev/catalyst/haproxy-health.git
cd haproxy-health
uv run --with . haproxy-health
# Or install in development mode
uv pip install -e .
haproxy-health
# After making changes
# 1. Edit haproxy_health/main.py
# 2. Test locally
# 3. Commit and push
# 4. Update deployments by restarting (clears uv cache)
Package structure:
haproxy-health/
├── pyproject.toml
└── haproxy_health/
├── __init__.py
└── main.py # Flask app with frontend/backend mapping
Troubleshooting
# Port already in use
sudo lsof -i :9300
sudo systemctl stop haproxy-health
# or use --port 9301
# Check service logs
journalctl -u haproxy-health.service -f
# Check listening sockets (should show both IPv4/IPv6)
ss -tlnp | grep 9300
# Check HAProxy socket permissions
ls -la /var/run/haproxy.sock
# Python version issues (requires 3.11+)
uv python install 3.11
uv python pin 3.11
Notes
- Port 9300 chosen to avoid conflicts with common exporters
- No authentication - restrict access via firewall
- Dual-stack IPv6/IPv4 support automatic
- HAProxy stats socket must be readable by service user