Documentation Refactor
This commit is contained in:
parent
3b8818e636
commit
a410b34521
47 changed files with 2065 additions and 3911 deletions
103
docs/concepts/index.md
Normal file
103
docs/concepts/index.md
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
---
|
||||
sidebar_position: 1
|
||||
sidebar_label: "Concepts"
|
||||
---
|
||||
|
||||
# Concepts
|
||||
|
||||
This section explains how EasyHAProxy works under the hood — the mental models that help you understand why things are configured the way they are.
|
||||
|
||||
## Service Discovery
|
||||
|
||||
EasyHAProxy runs a polling loop every N seconds (default 10, configurable via `EASYHAPROXY_REFRESH_CONF`). On each tick it:
|
||||
|
||||
1. **Queries your runtime** — Docker API for containers/services, Kubernetes API for Ingress objects, or reads the static YAML file.
|
||||
2. **Filters by label/annotation prefix** — only resources that carry the `easyhaproxy` prefix (or your custom `EASYHAPROXY_LABEL_PREFIX`) are considered.
|
||||
3. **Builds an intermediate structure** — an in-memory list of (host, port, backend) tuples called `easymapping`.
|
||||
4. **Runs plugins** — global plugins run once; domain plugins run once per host entry.
|
||||
5. **Renders `haproxy.cfg`** from a Jinja2 template using the `easymapping` data.
|
||||
6. **Reloads HAProxy** if the rendered config differs from the previous one (zero-downtime reload).
|
||||
|
||||
### Discovery mode comparison
|
||||
|
||||
| Mode | Source polled | Auth required |
|
||||
|------|--------------|---------------|
|
||||
| `docker` | Docker socket `/var/run/docker.sock` | Socket access |
|
||||
| `swarm` | Docker socket (Swarm API) | Socket access |
|
||||
| `kubernetes` | Kubernetes API server | RBAC (`get`/`list` on Ingress, Secret) |
|
||||
| `static` | File on disk | None |
|
||||
|
||||
## Configuration Pipeline
|
||||
|
||||
```
|
||||
Labels / Annotations / YAML file
|
||||
↓
|
||||
Discovery (Docker / Swarm / K8s / Static)
|
||||
↓
|
||||
parsed_object { IP → label map }
|
||||
↓
|
||||
[GLOBAL PLUGINS] ← executed once
|
||||
↓
|
||||
easymapping [ list of domain configs ]
|
||||
↓
|
||||
For each domain:
|
||||
[DOMAIN PLUGINS] ← executed per domain
|
||||
↓
|
||||
PluginResult snippets collected
|
||||
↓
|
||||
Jinja2 template render → haproxy.cfg
|
||||
↓
|
||||
HAProxy reload (if config changed)
|
||||
```
|
||||
|
||||
The key insight: **you never write `haproxy.cfg` by hand**. You express intent through labels/annotations/YAML, and EasyHAProxy translates that into valid HAProxy configuration on every discovery cycle.
|
||||
|
||||
## Plugin Execution Model
|
||||
|
||||
Plugins are Python classes that implement `PluginInterface`. They are discovered automatically from:
|
||||
|
||||
1. `/src/plugins/builtin/` — bundled plugins
|
||||
2. `/etc/easyhaproxy/plugins/` — your custom plugins
|
||||
|
||||
**Two execution types:**
|
||||
|
||||
### GLOBAL plugins
|
||||
|
||||
- Run **once per discovery cycle**, before any domain processing.
|
||||
- Receive the full `parsed_object` (all discovered services).
|
||||
- Use cases: cleanup tasks, global monitoring, DNS updates.
|
||||
- Example: `cleanup` plugin.
|
||||
|
||||
### DOMAIN plugins
|
||||
|
||||
- Run **once per discovered domain/host**.
|
||||
- Receive domain-specific context: domain name, port, label/annotation map.
|
||||
- Return `PluginResult` containing HAProxy config snippets to inject into the backend section.
|
||||
- Use cases: IP whitelisting, JWT validation, Cloudflare IP restoration, path blocking.
|
||||
- Examples: `cloudflare`, `deny_pages`, `jwt_validator`, `ip_whitelist`, `fastcgi`.
|
||||
|
||||
**Configuration precedence** (highest to lowest):
|
||||
1. Container labels / Ingress annotations (per-domain)
|
||||
2. Static YAML `plugins.config` block
|
||||
3. Environment variables `EASYHAPROXY_PLUGIN_<NAME>_<KEY>`
|
||||
|
||||
See the [Plugin Developer Guide](../guides/plugin-development.md) for how to build your own plugin.
|
||||
|
||||
## SSL/TLS Termination Model
|
||||
|
||||
SSL termination happens **at HAProxy**, not in your backend containers.
|
||||
|
||||
```
|
||||
Internet → HAProxy (TLS decryption) → Backend container (plain HTTP)
|
||||
```
|
||||
|
||||
Your containers should only serve HTTP on their internal port. HAProxy handles all TLS on ports 80/443.
|
||||
|
||||
**Certificate sources** (evaluated in this order for each domain):
|
||||
1. **ACME/Certbot** — if `certbot=true` label is set, EasyHAProxy runs Certbot HTTP-01 challenge automatically.
|
||||
2. **Volume-mounted PEM** — files in `/etc/easyhaproxy/certs/haproxy/{domain}.pem`.
|
||||
3. **Label-embedded PEM** — base64 certificate in the `sslcert` label.
|
||||
|
||||
Both ACME and manual certificates can coexist. Per domain, whichever source is configured takes precedence as shown above.
|
||||
|
||||
See [SSL setup](../guides/ssl.md) and [ACME/Let's Encrypt](../guides/acme.md) for step-by-step configuration.
|
||||
Loading…
Add table
Add a link
Reference in a new issue