1
0
Fork 0
docker-easy-haproxy/examples/static/README.md
Joao Gilberto Magalhaes 06d1d447f8 Add comprehensive Docker, Kubernetes, Swarm, and static configuration examples
- Added detailed `README.md` files with step-by-step instructions for Docker Compose, Kubernetes, Swarm, and static configuration examples.
- Included use cases for SSL setup, Let's Encrypt integration, load balancing, and advanced features like plugins and path-based routing.
- Documented environment variables, service labels, and troubleshooting tips across all examples.
- Enhanced examples with clear testing guidelines, SSL certificate generation steps, and debugging workflows.
2025-11-27 19:02:39 -05:00

462 lines
9.3 KiB
Markdown

# Static Configuration Example
This directory demonstrates EasyHAProxy using **static configuration** mode instead of dynamic service discovery.
## What is Static Mode?
Static mode uses a YAML configuration file (`config.yml`) to define HAProxy routing rules instead of discovering services automatically from Docker/Kubernetes/Swarm labels.
**Use cases:**
- Non-containerized backends
- Mixed environments (containers + VMs + bare metal)
- Fixed infrastructure where services don't change frequently
- Testing HAProxy configurations
---
## Files in This Example
- `conf/config.yml` - Static configuration defining hosts and routing
- `docker-compose.yml` - EasyHAProxy container mounting the config file
- `host1.local.pem` - Example SSL certificate
---
## Configuration Structure
### docker-compose.yml
```yaml
services:
haproxy:
image: byjg/easy-haproxy:4.6.0
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./conf:/etc/haproxy/static # Mount static config
- ./host1.local.pem:/certs/haproxy/host1.local.pem
environment:
EASYHAPROXY_DISCOVER: static # Use static mode
EASYHAPROXY_SSL_MODE: "loose"
ports:
- "80:80"
- "443:443"
- "1936:1936"
```
### conf/config.yml
```yaml
stats:
username: admin
password: password
port: 1936
customerrors: true
easymapping:
# HTTP Port 80 - Redirects to HTTPS
- port: 80
redirect:
host1.local: https://host1.local
www.host1.local: https://host1.local
# HTTPS Port 443
- port: 443
ssl: true
hosts:
host1.local:
containers:
- container:8080 # Backend container
```
---
## How It Works
### 1. Port Definitions
Each item in `easymapping` defines a listening port:
```yaml
easymapping:
- port: 80 # Listen on port 80
redirect: {...} # Optional redirects
- port: 443 # Listen on port 443
ssl: true # Enable SSL
hosts: {...} # Virtual hosts
```
### 2. Redirect Configuration
Redirect specific domains to different URLs:
```yaml
- port: 80
redirect:
host1.local: https://host1.local # HTTP → HTTPS
www.host1.local: https://host1.local # www → non-www + HTTPS
old.domain.com: https://new.domain.com # Domain change
```
### 3. Virtual Hosts
Define hosts and their backend containers:
```yaml
- port: 443
ssl: true
hosts:
host1.local: # Virtual host domain
containers:
- container:8080 # Backend: container_name:port
- another_container:3000 # Multiple backends = load balancing
host2.local:
containers:
- webserver:80
```
**Backend formats:**
- `container_name:port` - Docker container by name
- `ip_address:port` - Direct IP address
- `hostname:port` - Hostname resolution
### 4. SSL Configuration
```yaml
- port: 443
ssl: true # Enable SSL on this port
hosts:
secure.example.com:
containers:
- app:8080
```
SSL certificates must be placed in:
- `/certs/haproxy/<domain>.pem` inside container
- `./certs/<domain>.pem` on host (if volume mounted)
Certificate format: PEM file containing both certificate and private key.
### 5. Stats Interface
```yaml
stats:
username: admin
password: password
port: 1936
```
Access at: `http://localhost:1936`
---
## Running the Example
### 1. Start the Example
```bash
cd examples/static
docker compose up -d
```
### 2. Create Backend Container
The static config references `container:8080`. Create a container with this name:
```bash
docker run -d --name container \
-p 8080:8080 \
byjg/static-httpserver
```
Or add to `docker-compose.yml`:
```yaml
services:
# ... haproxy service ...
container:
image: byjg/static-httpserver
ports:
- "8080:8080"
```
### 3. Test
```bash
# Add to /etc/hosts:
# 127.0.0.1 host1.local www.host1.local
# Test HTTP redirect
curl -I http://host1.local
# Should return: HTTP/1.1 301 Moved Permanently
# Location: https://host1.local
# Test HTTPS
curl -k https://host1.local
# Access stats
open http://localhost:1936
# Username: admin
# Password: password
```
---
## Advanced Configuration
### Load Balancing Multiple Backends
```yaml
hosts:
api.example.com:
containers:
- api_server_1:8080
- api_server_2:8080
- api_server_3:8080
```
Default algorithm: round-robin
### Custom Balance Algorithm
```yaml
hosts:
api.example.com:
balance: leastconn # Use least connections instead of round-robin
containers:
- api_1:8080
- api_2:8080
```
**Available algorithms:**
- `roundrobin` - Distribute evenly (default)
- `leastconn` - Send to server with fewest connections
- `source` - Same client IP always goes to same server
### External Backends (Non-Docker)
```yaml
hosts:
legacy.example.com:
containers:
- 192.168.1.100:8080 # VM
- 192.168.1.101:8080 # Another VM
- database.local:5432 # Database server
```
### Health Checks
```yaml
hosts:
webapp.example.com:
containers:
- server1:8080
- server2:8080
healthcheck:
path: /health
interval: 5s
```
### Multiple Domains, Same Backend
```yaml
hosts:
example.com:
containers:
- webapp:8080
www.example.com:
containers:
- webapp:8080 # Same backend
app.example.com:
containers:
- webapp:8080 # Same backend
```
### Path-Based Routing
While static mode focuses on host-based routing, you can achieve path-based routing using redirects:
```yaml
- port: 80
redirect:
api.example.com/v1: https://api-v1.internal:8080
api.example.com/v2: https://api-v2.internal:8080
```
Or use HAProxy ACLs via custom templates (advanced).
---
## Plugins with Static Configuration
Enable plugins globally or per-host in static mode:
### Global Plugin Configuration
```yaml
plugins:
enabled: [cleanup]
config:
cleanup:
max_idle_time: 600
```
### Per-Host Plugin Configuration (via env vars)
Since static mode doesn't support per-host plugin configuration directly, use environment variables for domain-specific plugins:
```yaml
environment:
EASYHAPROXY_PLUGINS_ENABLED: cloudflare,deny_pages
EASYHAPROXY_PLUGIN_CLOUDFLARE_IP_LIST_PATH: /etc/haproxy/cloudflare_ips.lst
EASYHAPROXY_PLUGIN_DENY_PAGES_PATHS: /admin,/private
```
See [Using Plugins](../../docs/plugins.md) for more details.
---
## Comparison: Static vs. Dynamic Discovery
| Feature | Static Mode | Docker/Swarm/K8s Mode |
|---------|-------------|----------------------|
| Configuration | YAML file | Container labels / Ingress annotations |
| Backend types | Any (containers, VMs, IPs) | Containers only |
| Updates | Manual config edit + reload | Automatic discovery |
| Use case | Fixed infrastructure | Dynamic container environments |
| Plugin config | Global via YAML/env | Per-container/ingress via labels/annotations |
---
## Tips
1. **Reloading Configuration:**
```bash
# EasyHAProxy watches config.yml for changes
# Edit conf/config.yml, changes auto-reload
# Or manually restart:
docker compose restart haproxy
```
2. **Validate Configuration:**
```bash
# Check HAProxy config is valid
docker compose exec haproxy haproxy -c -f /etc/haproxy/haproxy.cfg
```
3. **View Generated Config:**
```bash
docker compose exec haproxy cat /etc/haproxy/haproxy.cfg
```
4. **Debugging:**
```bash
# Enable debug mode
docker compose up
# Watch logs in real-time
```
5. **SSL Certificate Management:**
```bash
# Generate self-signed cert
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout host.key -out host.crt \
-subj "/CN=host1.local"
# Combine into PEM
cat host.crt host.key > host1.local.pem
```
---
## Troubleshooting
### Backend Unreachable
**Error:** `503 Service Unavailable`
**Causes:**
- Backend container not running
- Wrong container name in config
- Wrong port number
- Network connectivity issues
**Debug:**
```bash
# Check backend container is running
docker ps | grep container_name
# Test backend directly
curl http://container_name:port
# Check HAProxy logs
docker compose logs haproxy
```
### Configuration Not Reloading
**Solution:**
```bash
# Restart HAProxy
docker compose restart haproxy
# Check file is mounted correctly
docker compose exec haproxy cat /etc/haproxy/static/config.yml
```
### SSL Certificate Not Found
**Error:** Certificate errors in logs
**Solution:**
```bash
# Verify certificate is mounted
docker compose exec haproxy ls -la /certs/haproxy/
# Check certificate format (must be PEM with cert + key)
openssl x509 -in host.pem -text -noout
openssl rsa -in host.pem -check
```
---
## Migration from Dynamic to Static
If you have Docker labels and want to convert to static config:
**Docker label:**
```yaml
labels:
easyhaproxy.http.host: api.example.com
easyhaproxy.http.port: 80
easyhaproxy.http.localport: 8080
easyhaproxy.http.redirect_ssl: true
```
**Static config equivalent:**
```yaml
easymapping:
- port: 80
redirect:
api.example.com: https://api.example.com
- port: 443
ssl: true
hosts:
api.example.com:
containers:
- container_name:8080
```
---
## Further Reading
- [Static Configuration Guide](../../docs/static.md)
- [Environment Variables](../../docs/environment-variable.md)
- [Using Plugins](../../docs/plugins.md)
- [SSL Configuration](../../docs/ssl.md)