1
0
Fork 0

Documentation Refactor

This commit is contained in:
Joao Gilberto Magalhaes 2026-02-20 01:05:37 -05:00
parent 3b8818e636
commit a410b34521
47 changed files with 2065 additions and 3911 deletions

View file

@ -0,0 +1,4 @@
{
"label": "Getting Started",
"position": 1
}

View file

@ -0,0 +1,66 @@
---
sidebar_position: 3
sidebar_label: "Docker"
---
# Docker
EasyHAProxy inspects running Docker containers, reads their labels, and configures HAProxy automatically.
:::warning Limitations
- You cannot mix Docker containers with Swarm containers.
- This method does not work with containers that use the `--network=host` option. See [limitations](../concepts/limitations.md) for details.
:::
## Step 1 — Create a shared network
```bash
docker network create easyhaproxy
```
It's recommended to use an external network so EasyHAProxy and your app containers can communicate.
## Step 2 — Run EasyHAProxy
```bash
docker run -d \
--name easy-haproxy-container \
-v /var/run/docker.sock:/var/run/docker.sock \
-e EASYHAPROXY_DISCOVER="docker" \
-p 80:80 \
-p 443:443 \
-p 1936:1936 \
--network easyhaproxy \
byjg/easy-haproxy
```
Mounting `/var/run/docker.sock` is required so EasyHAProxy can query the Docker API.
## Step 3 — Label your container
```bash
docker run -d \
--label easyhaproxy.http.host=example.org \
--label easyhaproxy.http.port=80 \
--label easyhaproxy.http.localport=8080 \
--network easyhaproxy \
my/image:tag
```
EasyHAProxy detects this container automatically and routes traffic from `example.org:80` to port 8080 in your container. You do not need to expose any container ports.
## Step 4 — Verify
Open `http://example.org` in your browser (or `curl http://example.org`). Traffic should reach your container.
---
## Full options
- [Container label reference](../reference/container-labels.md) — all available labels
- [Environment variable reference](../reference/environment-variables.md) — configure EasyHAProxy behavior
- [SSL certificates](../guides/ssl.md) — add custom TLS
- [ACME / Let's Encrypt](../guides/acme.md) — automatic certificate issuing
----
[Open source ByJG](http://opensource.byjg.com)

View file

@ -0,0 +1,51 @@
---
sidebar_position: 1
sidebar_label: "Getting Started"
---
# Getting Started with EasyHAProxy
EasyHAProxy dynamically builds `haproxy.cfg` from metadata on your running workloads — no HAProxy knowledge required.
## Choose your runtime
EasyHAProxy runs in two ways:
| Runtime | When to choose |
|---------|---------------|
| **Docker container** (`byjg/easy-haproxy`) | You already run Docker, Swarm, or Kubernetes |
| **Native host** (`easy-haproxy` CLI) | You want HAProxy on the host with full OS control — no Docker needed |
## Choose your discovery mode
Once running, EasyHAProxy discovers your services in one of four ways:
| Mode | How it works | Label/annotation format |
|------|-------------|------------------------|
| **Docker** | Reads labels from running containers on a Docker host | Container labels |
| **Swarm** | Reads labels from services in a Docker Swarm cluster | Service labels |
| **Kubernetes** | Reads `ingressClassName: easyhaproxy` Ingress resources | Ingress annotations |
| **Static** | Reads a hand-written YAML file you provide | YAML file |
## Quick-start guides
Pick the guide that matches your environment:
### Container runtimes (Docker image)
- **[Docker](docker.md)** — standalone Docker host, container labels
- **[Docker Swarm](swarm.md)** — overlay network, service labels
- **[Kubernetes](kubernetes.md)** — Ingress controller, DaemonSet/NodePort
- **[Static YAML](static.md)** — any environment, config file
### Native host (pip/uv package)
- **[Native install](native.md)** — HAProxy on the host, `easy-haproxy` CLI
## What's next?
After you have traffic flowing:
- **[Guides](../guides/ssl.md)** — SSL certificates, ACME/Let's Encrypt, plugins
- **[Concepts](../concepts/index.md)** — how service discovery and the config pipeline work
- **[Reference](../reference/environment-variables.md)** — full environment variable and label tables

View file

@ -0,0 +1,256 @@
---
sidebar_position: 1
sidebar_label: "Kubernetes"
---
# Kubernetes
EasyHAProxy acts as an Ingress controller for Kubernetes — it watches Ingress resources with `ingressClassName: easyhaproxy` and configures HAProxy automatically.
:::info How it works
EasyHAProxy queries all ingress definitions with either the
`spec.ingressClassName: easyhaproxy` field (recommended) or the deprecated annotation
`kubernetes.io/ingress.class: easyhaproxy-ingress` (for backward compatibility).
:::
## Deployment Modes
Choose the deployment mode that fits your infrastructure:
| Mode | Workload | Exposed Ports | Node Label | Recommended When |
|-----------|------------|------------------------|------------|-------------------------------|
| NodePort | Deployment | 31080 / 31443 / 31936 | No | Most setups **(recommended)** |
| ClusterIP | Deployment | cluster-internal only | No | Behind a LoadBalancer **(recommended)** |
| DaemonSet | DaemonSet | 80 / 443 / 1936 (host) | Yes | Bare-metal, special cases |
**NodePort** and **ClusterIP** run as a Deployment — no node label needed, and they survive node replacements safely.
**DaemonSet** binds to host ports and requires a node label (`easyhaproxy/node=master`) via `nodeAffinity`. The label must be manually reapplied after any node replacement, which can cause outages. Use only for bare-metal or special-case setups.
EasyHAProxy detects its deployment mode automatically (`EASYHAPROXY_DEPLOYMENT_MODE=auto`). See the [environment variable reference](../reference/environment-variables.md#kubernetes) for manual override options.
## Step 1 — Install EasyHAProxy
```bash
kubectl create namespace easyhaproxy
```
### NodePort (recommended)
Exposes HAProxy on NodePort `31080` (HTTP), `31443` (HTTPS), and `31936` (stats). Point your DNS or external load balancer to any node IP on these ports.
```bash
kubectl apply -f \
https://raw.githubusercontent.com/byjg/docker-easy-haproxy/6.0.0/deploy/kubernetes/easyhaproxy-nodeport.yml
```
### ClusterIP (behind a LoadBalancer)
Cluster-internal only. Pair with an external cloud LoadBalancer or `kubectl port-forward` for local testing.
```bash
kubectl apply -f \
https://raw.githubusercontent.com/byjg/docker-easy-haproxy/6.0.0/deploy/kubernetes/easyhaproxy-clusterip.yml
```
### DaemonSet (special cases — requires node label)
:::warning Requires node label maintenance
The node label must be reapplied after any node replacement. Failing to do so will cause an outage.
:::
```bash
# Label the target node first
kubectl label nodes node-01 "easyhaproxy/node=master"
kubectl apply -f \
https://raw.githubusercontent.com/byjg/docker-easy-haproxy/6.0.0/deploy/kubernetes/easyhaproxy-daemonset.yml
```
If you need to configure environment variables (log levels, stats password, etc.), see the [environment variable reference](../reference/environment-variables.md).
## Step 2 — Create an Ingress
```yaml
kind: Ingress
metadata:
name: example-ingress
namespace: example
spec:
ingressClassName: easyhaproxy
rules:
- host: example.org
http:
paths:
- backend:
service:
name: example-service
port:
number: 8080
pathType: ImplementationSpecific
```
EasyHAProxy routes traffic from `example.org:80` to your service at port 8080. No container port exposure needed.
:::note Backward Compatibility
The deprecated annotation `kubernetes.io/ingress.class: easyhaproxy-ingress` is still supported but `spec.ingressClassName` is recommended for new deployments.
:::
## Step 3 — Verify
```bash
curl http://example.org
```
---
## Kubernetes Annotations
Customize EasyHAProxy behavior per-ingress using annotations. For the full annotations reference, see [Container Labels — Kubernetes Ingress Annotations](../reference/container-labels.md#kubernetes-ingress-annotations).
**Important**: Annotations apply to all hosts in the ingress configuration.
## Using Plugins
Add the `easyhaproxy.plugins` annotation with a comma-separated list of plugin names:
```yaml
metadata:
annotations:
easyhaproxy.plugins: "cloudflare,deny_pages"
easyhaproxy.plugin.deny_pages.paths: "/wp-admin,/wp-login.php"
easyhaproxy.plugin.deny_pages.status_code: "404"
```
For full plugin documentation, see the [Using Plugins](../guides/plugins.md) guide.
## Loading Plugin Configuration from Kubernetes Secrets
EasyHAProxy supports loading sensitive plugin configuration values from Kubernetes Secrets using the `k8s_secret` pattern:
```yaml
# Auto-detect key (tries common variations):
easyhaproxy.plugin.{plugin_name}.k8s_secret.{config_key}: "secret_name"
# Explicit key (no variations):
easyhaproxy.plugin.{plugin_name}.k8s_secret.{config_key}: "secret_name/key_name"
```
### How It Works
1. You create a Kubernetes Secret with your sensitive data
2. You reference the secret in your ingress annotation using the `k8s_secret` pattern
3. EasyHAProxy reads the secret from the same namespace as the ingress
4. EasyHAProxy transforms the annotation to inject the secret value
5. The plugin receives the value as if it was provided directly in the annotation
### Complete Example
```yaml
---
apiVersion: v1
kind: Secret
metadata:
name: jwt-pubkey-secret
namespace: production
type: Opaque
stringData:
pubkey: |
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
namespace: production
annotations:
easyhaproxy.plugins: "jwt_validator"
easyhaproxy.plugin.jwt_validator.algorithm: "RS256"
easyhaproxy.plugin.jwt_validator.issuer: "https://auth.example.com/"
easyhaproxy.plugin.jwt_validator.audience: "https://api.example.com"
easyhaproxy.plugin.jwt_validator.k8s_secret.pubkey: "jwt-pubkey-secret"
spec:
ingressClassName: easyhaproxy
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
```
### Priority Order
1. **Explicit annotation** (e.g., `easyhaproxy.plugin.jwt_validator.pubkey: "value"`)
2. **k8s_secret annotation** (e.g., `easyhaproxy.plugin.jwt_validator.k8s_secret.pubkey: "secret"`)
### Security Considerations
- Secrets are read from the **same namespace** as the ingress (no cross-namespace access)
- EasyHAProxy needs RBAC permissions to read secrets (included in default deployment)
- Use Kubernetes RBAC to control which service accounts can read which secrets
## ACME / Let's Encrypt
Add the `easyhaproxy.certbot` annotation to enable automatic certificate issuing:
```yaml
kind: Ingress
metadata:
annotations:
easyhaproxy.certbot: 'true'
name: example-ingress
namespace: example
spec:
ingressClassName: easyhaproxy
```
More info in the [ACME guide](../guides/acme.md). Make sure ports 80 and 443 are publicly reachable.
## Custom SSL Certificates
Create a secret with your certificate and key and associate it with your ingress:
```yaml
---
apiVersion: v1
kind: Secret
metadata:
name: host2-tls
namespace: default
data:
tls.crt: base64 of your certificate
tls.key: base64 of your certificate private key
type: kubernetes.io/tls
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-example
namespace: default
spec:
ingressClassName: easyhaproxy
tls:
- hosts:
- host2.local
secretName: host2-tls
rules:
...
```
## Important Limitations
- The implementation doesn't support all ingress properties or wildcard domains.
- EasyHAProxy reads all `spec.rules[].host` values but parses only the **first path** per rule.
----
[Open source ByJG](http://opensource.byjg.com)

View file

@ -0,0 +1,130 @@
---
sidebar_position: 5
sidebar_label: "Native (pip/uv)"
---
# Native install (pip / uv)
EasyHAProxy can run directly on any Linux or macOS host without Docker, using the `easyhaproxy` Python package. HAProxy is installed on the host; EasyHAProxy manages it.
## Prerequisites
HAProxy must be installed and available in your system `PATH` before running `easy-haproxy`.
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs>
<TabItem value="debian" label="Debian / Ubuntu" default>
```bash
sudo apt install haproxy
```
</TabItem>
<TabItem value="rhel" label="RHEL / Fedora">
```bash
sudo dnf install haproxy
```
</TabItem>
<TabItem value="macos" label="macOS">
```bash
brew install haproxy
```
</TabItem>
</Tabs>
## Installation
### Recommended: `uv tool` (system-wide, isolated)
[`uv`](https://docs.astral.sh/uv/) installs `easyhaproxy` into its own isolated environment and exposes the `easy-haproxy` binary in `~/.local/bin/`.
```bash
# Install uv (if not already installed)
curl -LsSf https://astral.sh/uv/install.sh | sh
# Install easyhaproxy as a tool
uv tool install easyhaproxy
# Make sure ~/.local/bin is in PATH (one-time setup)
uv tool update-shell
```
### Alternative: `pip`
```bash
pip install easyhaproxy
```
:::note Virtual environments
When installing inside a virtual environment, `easy-haproxy` is only available while the environment is activated. For system-wide use, prefer `uv tool install`.
:::
## Quick start
### Static mode (bare-metal / VM)
```bash
mkdir -p ~/easyhaproxy/static
cat > ~/easyhaproxy/static/config.yml <<EOF
containers:
"myapp.example.com:80":
ip: ["127.0.0.1:3000"]
EOF
easy-haproxy --discover static
```
### Docker mode
```bash
easy-haproxy --discover docker
```
### Kubernetes mode
```bash
easy-haproxy --discover kubernetes
```
## Running as a systemd service
```ini title="/etc/systemd/system/easy-haproxy.service"
[Unit]
Description=EasyHAProxy
After=network.target
[Service]
ExecStart=/usr/local/bin/easy-haproxy --discover static --haproxy-password mysecret
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
```
```bash
sudo systemctl daemon-reload
sudo systemctl enable --now easy-haproxy
```
:::tip Adjust ExecStart path
Run `which easy-haproxy` to get the correct binary path. If installed with `uv tool`, it is typically `/root/.local/bin/easy-haproxy` when running as root.
:::
---
## Full options
- [CLI Reference](../reference/cli.md) — all flags and environment variables
- [ACME / Let's Encrypt](../guides/acme.md) — automatic certificate issuing
- [Plugins](../guides/plugins.md) — extend functionality
----
[Open source ByJG](http://opensource.byjg.com)

View file

@ -0,0 +1,105 @@
---
sidebar_position: 4
sidebar_label: "Static YAML"
---
# Static YAML
Use this mode to configure EasyHAProxy from a hand-written YAML file. Works for any backend — Docker containers, VMs, bare-metal servers, or anything reachable by IP/hostname.
:::tip Live Reload
EasyHAProxy monitors this file for changes and automatically reconfigures HAProxy when any changes are detected.
:::
## Step 1 — Write a minimal config file
```yaml
containers:
"myapp.example.com:80":
ip: ["10.0.0.5:3000"]
```
Save this as `config.yml`.
## Step 2 — Run EasyHAProxy
```bash
docker run -d \
--name easy-haproxy-container \
-v /my/static/:/etc/easyhaproxy/static/ \
-e EASYHAPROXY_DISCOVER="static" \
-p 80:80 \
-p 443:443 \
-p 1936:1936 \
byjg/easy-haproxy
```
:::tip Docker Socket Optional
Mounting `/var/run/docker.sock` is not required in static discovery mode.
:::
## Step 3 — Verify
```bash
curl http://myapp.example.com
```
---
## Full YAML reference
```yaml
stats:
username: admin # Optional (default "admin")
password: password # If omitted, stats are public with no password
port: 1936 # Optional (default 1936)
customerrors: true # Optional (default false)
ssl_mode: default # Optional
logLevel:
certbot: DEBUG # Optional. Can be: TRACE,DEBUG,INFO,WARN,ERROR,FATAL
easyhaproxy: DEBUG # Optional. Can be: TRACE,DEBUG,INFO,WARN,ERROR,FATAL
haproxy: INFO # Optional. Can be: TRACE,DEBUG,INFO,WARN,ERROR,FATAL
certbot:
email: "acme@example.org" # If set, enables ACME/Certbot
autoconfig: "" # Well-known CA shorthand (e.g. letsencrypt)
eab_hmac_key: "" # Required by some CAs
eab_kid: "" # Required by some CAs
server: False # ACME endpoint URL (or False for Let's Encrypt)
retry_count: 60 # Retry after rate limit
containers:
# Format: "hostname:port"
"host1.com.br:80":
ip: ["container:5000"] # Endpoints: "address:localport"
certbot: true # Request certbot certificate
redirect_ssl: true # Redirect HTTP to HTTPS
mode: http # Default `http`. Can be http or tcp
# HTTPS version (SSL)
"host1.com.br:443":
ip: ["container:80"]
ssl: true # Enable SSL for this port
# Redirect www → main domain
"www.host1.com.br:80":
ip: ["container:5000"]
redirect_ssl: true
```
:::note SSL Certificates in Static Mode
The only way to provide SSL certificates in static configuration mode is to map the certificate files as a Docker volume. See the [SSL documentation](../guides/ssl.md) to learn how to configure this.
:::
---
## Full options
- [Container label reference](../reference/container-labels.md) — label semantics also apply to static YAML keys
- [Environment variable reference](../reference/environment-variables.md) — configure EasyHAProxy behavior
----
[Open source ByJG](http://opensource.byjg.com)

View file

@ -0,0 +1,100 @@
---
sidebar_position: 2
sidebar_label: "Docker Swarm"
---
# Docker Swarm
EasyHAProxy inspects Docker Swarm services, reads their labels, and configures HAProxy automatically across all nodes.
:::tip Docker Swarm Advantages
- **Container Discovery**: Docker Swarm facilitates the discovery of containers within the cluster.
- **Remote Node Management**: Manage containers across multiple nodes while EasyHAProxy configures HAProxy seamlessly.
:::
:::warning Limitations
- You cannot mix Docker containers with Swarm containers.
- This method does not work with containers that use the `--network=host` option. See [limitations](../concepts/limitations.md) for details.
:::
## Step 1 — Create an overlay network
```bash
docker network create -d overlay --attachable easyhaproxy
```
## Step 2 — Deploy EasyHAProxy as a Swarm stack
```yaml
services:
haproxy:
image: byjg/easy-haproxy:6.0.0
volumes:
- /var/run/docker.sock:/var/run/docker.sock
deploy:
replicas: 1
environment:
EASYHAPROXY_DISCOVER: swarm
EASYHAPROXY_SSL_MODE: "loose"
HAPROXY_CUSTOMERRORS: "true"
HAPROXY_USERNAME: admin
HAPROXY_PASSWORD: password
HAPROXY_STATS_PORT: 1936
ports:
- "80:80/tcp"
- "443:443/tcp"
- "1936:1936/tcp"
networks:
- easyhaproxy
networks:
easyhaproxy:
external: true
```
```bash
docker stack deploy --compose-file docker-compose.yml easyhaproxy
```
:::danger Single Replica Only
**Do not** add more than one replica for EasyHAProxy. To understand why, see the [limitations](../concepts/limitations.md) page.
:::
## Step 3 — Label your service
```yaml
services:
container:
image: my/image:tag
deploy:
replicas: 1
labels:
easyhaproxy.http.host: host1.local
easyhaproxy.http.port: 80
easyhaproxy.http.localport: 8080
networks:
- easyhaproxy
networks:
easyhaproxy:
external: true
```
EasyHAProxy detects this service automatically and routes traffic from `host1.local:80` to your container. You do not need to expose any container ports.
## Step 4 — Verify
```bash
curl http://host1.local
```
---
## Full options
- [Container label reference](../reference/container-labels.md) — all available labels
- [Environment variable reference](../reference/environment-variables.md) — configure EasyHAProxy behavior
- [Docker guide](docker.md) — more detailed Docker examples
----
[Open source ByJG](http://opensource.byjg.com)