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": "Reference",
"position": 4
}

81
docs/reference/cli.md Normal file
View file

@ -0,0 +1,81 @@
---
sidebar_position: 1
sidebar_label: "CLI Reference"
---
# CLI Reference
The `easy-haproxy` command is the native binary installed via `pip` or `uv`. Every option can be set as a **CLI flag** or an **environment variable**. CLI flags take precedence over environment variables.
```
easy-haproxy [OPTIONS]
```
For installation instructions, see [Native install](../getting-started/native.md).
## Core
| Flag | Environment Variable | Default | Description |
|--------------------------|----------------------------|------------------------------------------------------|-----------------------------------------------------------|
| `--discover MODE` | `EASYHAPROXY_DISCOVER` | **required** | Discovery mode: `static`, `docker`, `swarm`, `kubernetes` |
| `--base-path PATH` | `EASYHAPROXY_BASE_PATH` | `/etc/easyhaproxy` (root) `~/easyhaproxy` (non-root) | Base directory for all EasyHAProxy files |
| `--label-prefix PREFIX` | `EASYHAPROXY_LABEL_PREFIX` | `easyhaproxy` | Label/annotation prefix used to discover services |
| `--ssl-mode MODE` | `EASYHAPROXY_SSL_MODE` | `default` | TLS policy: `strict`, `default`, or `loose` |
| `--refresh-conf SECONDS` | `EASYHAPROXY_REFRESH_CONF` | `10` | Polling interval for configuration changes |
| `--customer-errors BOOL` | `HAPROXY_CUSTOMERRORS` | `false` | Enable custom HAProxy HTML error pages |
## Logging
| Flag | Environment Variable | Default | Description |
|-----------------------------|-------------------------|----------|---------------------------|
| `--log-level LEVEL` | `EASYHAPROXY_LOG_LEVEL` | `DEBUG` | EasyHAProxy log level |
| `--haproxy-log-level LEVEL` | `HAPROXY_LOG_LEVEL` | `INFO` | HAProxy process log level |
| `--certbot-log-level LEVEL` | `CERTBOT_LOG_LEVEL` | `DEBUG` | Certbot log level |
Valid levels: `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`, `FATAL`
## Stats Dashboard
| Flag | Environment Variable | Default | Description |
|--------------------------------------|-----------------------------|--------------|---------------------------------------------|
| `--haproxy-password PASSWORD` | `HAPROXY_PASSWORD` | *(disabled)* | Enable stats dashboard with this password |
| `--haproxy-username USERNAME` | `HAPROXY_USERNAME` | `admin` | Stats dashboard username |
| `--haproxy-stats-port PORT` | `HAPROXY_STATS_PORT` | `1936` | Stats dashboard port |
| `--haproxy-stats-cors-origin ORIGIN` | `HAPROXY_STATS_CORS_ORIGIN` | *(none)* | Allowed CORS origin for the stats dashboard |
:::tip
The stats dashboard is only enabled when `--haproxy-password` (or `HAPROXY_PASSWORD`) is set.
:::
## ACME / Certbot (SSL certificates)
| Flag | Environment Variable | Default | Description |
|---------------------------------------|--------------------------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------|
| `--certbot-email EMAIL` | `EASYHAPROXY_CERTBOT_EMAIL` | *(none)* | Contact email — enables ACME when set |
| `--certbot-autoconfig CA` | `EASYHAPROXY_CERTBOT_AUTOCONFIG` | *(none)* | Well-known CA shorthand: `letsencrypt`, `letsencrypt_test`, `buypass`, `buypass_test`, `sslcom_rca`, `sslcom_ecc`, `google`, `google_test`, `zerossl` |
| `--certbot-server URL` | `EASYHAPROXY_CERTBOT_SERVER` | *(none)* | Custom ACME server directory URL |
| `--certbot-eab-kid KID` | `EASYHAPROXY_CERTBOT_EAB_KID` | *(none)* | External Account Binding key ID |
| `--certbot-eab-hmac-key KEY` | `EASYHAPROXY_CERTBOT_EAB_HMAC_KEY` | *(none)* | External Account Binding HMAC key |
| `--certbot-retry-count N` | `EASYHAPROXY_CERTBOT_RETRY_COUNT` | `60` | Iterations before retrying after a rate limit |
| `--certbot-preferred-challenges TYPE` | `EASYHAPROXY_CERTBOT_PREFERRED_CHALLENGES` | `http` | ACME challenge type |
| `--certbot-manual-auth-hook SCRIPT` | `EASYHAPROXY_CERTBOT_MANUAL_AUTH_HOOK` | *(none)* | Path to a manual auth hook script for certbot |
See the full [ACME documentation](../guides/acme.md) for details.
## Plugins
| Flag | Environment Variable | Default | Description |
|---------------------------------|--------------------------------------|----------|-------------------------------------------|
| `--plugins-enabled LIST` | `EASYHAPROXY_PLUGINS_ENABLED` | *(none)* | Comma-separated list of plugins to enable |
| `--plugins-abort-on-error BOOL` | `EASYHAPROXY_PLUGINS_ABORT_ON_ERROR` | `false` | Abort startup if a plugin fails to load |
See the [plugins guide](../guides/plugins.md) for available plugins.
## Kubernetes
| Flag | Environment Variable | Default | Description |
|--------------------------------------------|--------------------------------------|----------|----------------------------------------------|
| `--update-ingress-status BOOL` | `EASYHAPROXY_UPDATE_INGRESS_STATUS` | `true` | Update Ingress status with load-balancer IP |
| `--deployment-mode MODE` | `EASYHAPROXY_DEPLOYMENT_MODE` | `auto` | Deployment mode: `auto`, `single`, `cluster` |
| `--external-hostname HOSTNAME` | `EASYHAPROXY_EXTERNAL_HOSTNAME` | *(none)* | External hostname reported in Ingress status |
| `--ingress-status-update-interval SECONDS` | `EASYHAPROXY_STATUS_UPDATE_INTERVAL` | `30` | Interval to update Ingress status |

View file

@ -0,0 +1,170 @@
---
sidebar_position: 3
sidebar_label: "Container Labels"
---
# Container Labels
## Container (Docker or Swarm) labels
| Label | Description | Default | Example |
|---------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|------------------------------------------------------------------------------------------------------------------|
| easyhaproxy.[definition].host | Host(s) HAProxy is listening. More than one host use comma as delimiter | **required** | somehost.com OR host1.com,host2.com |
| easyhaproxy.[definition].mode | (Optional) Is this `http` or `tcp` mode in HAProxy. | http | http or tcp |
| easyhaproxy.[definition].port | (Optional) Port HAProxy will listen for the host. | 80 | 3000 |
| easyhaproxy.[definition].localport | (Optional) Port container is listening. | 80 | 8080 |
| easyhaproxy.[definition].redirect | (Optional) JSON containing key/value pair from host/to URL redirect. | *empty* | \{"foo.com":"https://bla.com", "bar.com":"https://bar.org"} |
| easyhaproxy.[definition].sslcert | (Optional) Cert PEM Base64 encoded. Do not use this if `certbot` is enabled. | *empty* | base64 cert + key |
| easyhaproxy.[definition].ssl | (Optional) If `true` you need to provide certificate as a file. See below. Do not use with `sslcert`. | false | true or false |
| easyhaproxy.[definition].ssl-check | (Optional) `ssl`, enable health check via SSL in `mode tcp` | *empty* | ssl |
| easyhaproxy.[definition].certbot | (Optional) Generate certificate with certbot. Do not use with `sslcert` parameter. More info [here](../guides/acme.md). | false | true OR false |
| easyhaproxy.[definition].redirect_ssl | (Optional) Redirect all requests to https | false | true OR false |
| easyhaproxy.[definition].clone_to_ssl | (Optional) It copies the configuration to HTTPS(443) and disable SSL from the current config. **Do not use** this with `ssl` or `certbot` parameters | false | true OR false |
| easyhaproxy.[definition].balance | (Optional) HAProxy balance algorithm. See [HAProxy documentation](https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4.2-balance) | roundrobin | roundrobin, source, uri, url_param, hdr, rdp-cookie, leastconn, first, static-rr, rdp-cookie, hdr_dom, map-based |
| easyhaproxy.[definition].proto | (Optional) Backend server protocol (e.g., fcgi for PHP-FPM, h2 for HTTP/2) | *empty* | fcgi, h2 |
| easyhaproxy.[definition].socket | (Optional) Unix socket path for backend connection (alternative to host:port) | *empty* | /run/php/php-fpm.sock |
:::info Understanding Definitions
The `[definition]` is a string identifier that groups related configuration labels together. Different definitions create separate HAProxy configurations.
A single container can have multiple definitions to expose different services or ports.
:::
## Configurations
### Single Definition
```bash title="Single service configuration"
docker run \
--label easyhaproxy.webapi.port=80\
--label easyhaproxy.webapi.host=byjg.com.br \
....
```
### Multiple Definitions on the same container
```bash title="Multiple services on one container"
docker run \
--label easyhaproxy.express.port=80 \
--label easyhaproxy.express.localport=3000 \
--label easyhaproxy.express.host=express.byjg.com.br \
--label easyhaproxy.admin.port=80 \
--label easyhaproxy.admin.localport=3001 \
--label easyhaproxy.admin.host=admin.byjg.com.br \
.... \
some/myimage
```
### Multiple hosts on the same container
```bash title="Multiple hosts for one service"
docker run \
--label easyhaproxy.express.port=80 \
--label easyhaproxy.express.localport=3000 \
--label easyhaproxy.express.host=express.byjg.com.br,admin.byjg.com.br \
.... \
some/myimage
```
If you are using docker-compose you can use this way:
```yaml
services:
mycontainer:
image: some/myimage
labels:
easyhaproxy.express.port: 80
easyhaproxy.express.localport: 3000
easyhaproxy.express.host: >-
express.byjg.com.br,
admin.byjg.com.br
```
### TCP Mode
Set `easyhaproxy.[definition].mode=tcp` if your application uses TCP protocol instead of HTTP.
```bash title="TCP mode configuration"
docker run \
--label easyhaproxy.example.mode=tcp \
--label easyhaproxy.example.port=3306
--label easyhaproxy.example.localport=3306
.... \
some/tcp-service
```
### FastCGI (PHP-FPM) Support
EasyHAProxy supports FastCGI protocol for PHP-FPM and other FastCGI applications.
#### Using Unix Socket
```yaml title="PHP-FPM with Unix socket"
services:
php-fpm:
image: php:8.2-fpm
labels:
easyhaproxy.fcgi.host: phpapp.local
easyhaproxy.fcgi.port: 80
easyhaproxy.fcgi.socket: /run/php/php-fpm.sock
easyhaproxy.fcgi.proto: fcgi
volumes:
- /run/php:/run/php
```
#### Using TCP Connection
```yaml title="PHP-FPM with TCP connection"
services:
php-fpm:
image: php:8.2-fpm
labels:
easyhaproxy.fcgi.host: phpapp.local
easyhaproxy.fcgi.port: 80
easyhaproxy.fcgi.localport: 9000
easyhaproxy.fcgi.proto: fcgi
```
**Generated HAProxy Configuration:**
```
backend srv_phpapp_local_80
balance roundrobin
mode http
option forwardfor
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Forwarded-Host %[req.hdr(Host)]
http-request set-header X-Request-ID %[uuid()]
server srv-0 /run/php/php-fpm.sock check weight 1 proto fcgi
```
### Redirect Domains
```bash title="Domain redirect configuration"
docker run \
--label easyhaproxy.[definition].redirect='{"www.byjg.com.br":"http://byjg.com.br","byjg.com":"http://byjg.com.br"}'
```
---
## Kubernetes Ingress Annotations
When using Kubernetes, configure EasyHAProxy behavior with these annotations on your Ingress resources. Annotations apply to **all hosts** in the ingress configuration.
| Annotation | Description | Default | Example |
|-------------------------------------|--------------------------------------------------------------------------------------|------------|-----------------------------|
| kubernetes.io/ingress.class | (deprecated) Activate EasyHAProxy. Use `spec.ingressClassName` instead. | *optional* | easyhaproxy-ingress |
| easyhaproxy.redirect_ssl | (optional) Boolean. Force redirect all endpoints to HTTPS. | false | true or false |
| easyhaproxy.certbot | (optional) Boolean. Request certbot certificates for the ingress domains. | false | true or false |
| easyhaproxy.redirect | (optional) JSON. Key pair with a domain and its destination. | *empty* | \{"domain":"redirect_url"} |
| easyhaproxy.mode | (optional) Set the HTTP mode for that connection. | http | http or tcp |
| easyhaproxy.listen_port | (optional) Override the HTTP listen port created for that ingress. | 80 | 8081 |
| easyhaproxy.plugins | (optional) Comma-separated list of plugins to enable for this ingress. | *empty* | cloudflare,deny_pages |
| easyhaproxy.plugin.`{name}`.`{key}` | (optional) Plugin-specific configuration (see [Using Plugins](../guides/plugins.md)) | *varies* | See plugin docs |
For annotation usage examples, see the [Kubernetes getting started guide](../getting-started/kubernetes.md).
----
[Open source ByJG](http://opensource.byjg.com)

View file

@ -0,0 +1,49 @@
---
sidebar_position: 2
sidebar_label: "Environment Variables"
---
# Docker environment variables
| Environment Variable | Description | Default |
|---------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------|
| EASYHAPROXY_DISCOVER | How the services will be discovered to create `haproxy.cfg`: `static`, `docker`, `swarm` or `kubernetes` | **required** |
| EASYHAPROXY_LABEL_PREFIX | (Optional) The key will search for matching resources. | `easyhaproxy` |
| EASYHAPROXY_BASE_PATH | (Optional) Base directory for all EasyHAProxy files. All paths (config, certs, plugins, www) are constructed relative to this base. | `/etc/easyhaproxy` |
| EASYHAPROXY_CERTBOT_* | (Optional) Enable Let's Encrypt or any other ACME certificate. See more: [acme](../guides/acme.md) | *empty* |
| EASYHAPROXY_SSL_MODE | (Optional) `strict` supports only the most recent TLS version; `default` good SSL integration with recent browsers; `loose` supports all old SSL protocols for old browsers (not recommended). | `default` |
| EASYHAPROXY_REFRESH_CONF | (Optional) Check for new containers/services every N seconds. | 10 |
| EASYHAPROXY_LOG_LEVEL | (Optional) The log level for EasyHAproxy messages. Available: TRACE,DEBUG,INFO,WARN,ERROR,FATAL | DEBUG |
| CERTBOT_LOG_LEVEL | (Optional) The log level for Certbot messages. Available: TRACE,DEBUG,INFO,WARN,ERROR,FATAL | DEBUG |
| HAPROXY_LOG_LEVEL | (Optional) The log level for HAProxy messages. Available: TRACE,DEBUG,INFO,WARN,ERROR,FATAL | INFO |
| HAPROXY_USERNAME | (Optional) The HAProxy username for the statistics endpoint (used only when `HAPROXY_PASSWORD` is set). | `admin` |
| HAPROXY_PASSWORD | (Optional) The HAProxy password to the statistics endpoint. Stats are **disabled** unless this is defined. | *empty* |
| HAPROXY_STATS_PORT | (Optional) The HAProxy port to the statistics. If set to `false`, disable statistics. Only applies when `HAPROXY_PASSWORD` is defined. | `1936` |
| HAPROXY_STATS_CORS_ORIGIN | (Optional) Enable CORS for the HAProxy stats dashboard by specifying the allowed origin (e.g., `http://localhost:3000`). Only applies when `HAPROXY_PASSWORD` is defined. | *empty* |
| HAPROXY_CUSTOMERRORS | (Optional) If HAProxy will use custom HTML errors. true/false. | `false` |
:::tip HAProxy Stats
Statistics are only configured when `HAPROXY_PASSWORD` is set. Without a password, the stats section is not generated.
:::
:::note ACME/Certbot Environment Variables
For ACME/Certbot configuration (Let's Encrypt, ZeroSSL, etc.), see the [ACME documentation](../guides/acme.md#environment-variables) for the complete list of `EASYHAPROXY_CERTBOT_*` variables.
:::
## Kubernetes
These variables apply only when `EASYHAPROXY_DISCOVER=kubernetes`. They control how EasyHAProxy updates Ingress resources with load-balancer IP information.
| Environment Variable | Description | Default |
|------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------|---------|
| EASYHAPROXY_UPDATE_INGRESS_STATUS | Update Ingress resources with the load-balancer IP. Set to `false` to disable. | `true` |
| EASYHAPROXY_DEPLOYMENT_MODE | How to detect and report Ingress IPs: `auto`, `daemonset`, `nodeport`, or `clusterip`. `auto` inspects pod owner references and service type automatically. | `auto` |
| EASYHAPROXY_EXTERNAL_HOSTNAME | Hostname to report in Ingress status when using ClusterIP mode without a cloud LoadBalancer. | *(none)* |
| EASYHAPROXY_STATUS_UPDATE_INTERVAL | Seconds between Ingress status update cycles. | `30` |
:::tip Deployment mode auto-detection
`EASYHAPROXY_DEPLOYMENT_MODE=auto` is recommended. EasyHAProxy inspects its own pod owner references (DaemonSet vs Deployment) and Service type (NodePort vs ClusterIP) to determine the correct IP source. Override only if auto-detection gives wrong results.
:::
----
[Open source ByJG](http://opensource.byjg.com)

115
docs/reference/helm.md Normal file
View file

@ -0,0 +1,115 @@
---
sidebar_position: 6
sidebar_label: "Helm Values"
---
# Helm Values Reference
Complete reference for all configurable values in the `byjg/easyhaproxy` Helm chart.
## Image Configuration
| Value | Description | Default |
|---|---|---|
| `image.repository` | Container image repository | `byjg/easy-haproxy` |
| `image.tag` | Image tag. Defaults to the chart `appVersion`. | `""` |
| `image.pullPolicy` | Image pull policy | `Always` |
| `imagePullSecrets` | List of image pull secret names | `[]` |
| `nameOverride` | Override the chart name | `""` |
| `fullnameOverride` | Override the full release name | `""` |
## Deployment Mode
Controls whether EasyHAProxy runs as a **Deployment** (with a Service) or a **DaemonSet** (binding to host ports).
| Value | Description | Default |
|---|---|---|
| `replicaCount` | Number of replicas (only used when `service.create: true`) | `1` |
| `service.create` | `true` → Deployment + Service (NodePort or ClusterIP). `false` → DaemonSet with host ports. | `false` |
| `service.type` | Service type when `service.create: true`: `NodePort` or `ClusterIP` | `ClusterIP` |
| `service.annotations` | Annotations to add to the Service resource | `{}` |
:::tip Recommended mode
Set `service.create: true` and `service.type: NodePort` for most setups. DaemonSet mode (`service.create: false`) requires maintaining a node label across node replacements, which can cause outages if forgotten.
:::
## Port Binding
| Value | Description | Default |
|---|---|---|
| `binding.ports.http` | HTTP port | `80` |
| `binding.ports.https` | HTTPS port | `443` |
| `binding.ports.stats` | HAProxy stats port | `1936` |
| `binding.additionalPorts` | List of additional ports to expose | `[]` |
## EasyHAProxy Settings
| Value | Description | Default |
|---|---|---|
| `easyhaproxy.stats.username` | HAProxy stats dashboard username | `admin` |
| `easyhaproxy.stats.password` | HAProxy stats dashboard password | `password` |
| `easyhaproxy.refresh` | Seconds between service discovery polls | `"10"` |
| `easyhaproxy.customErrors` | Enable custom HTML error pages | `"true"` |
| `easyhaproxy.sslMode` | TLS mode: `strict`, `default`, or `loose` | `loose` |
| `easyhaproxy.logLevel.certbot` | Log level for Certbot | `DEBUG` |
| `easyhaproxy.logLevel.easyhaproxy` | Log level for EasyHAProxy | `DEBUG` |
| `easyhaproxy.logLevel.haproxy` | Log level for HAProxy | `DEBUG` |
| `easyhaproxy.certbot.email` | Email address for Let's Encrypt / ACME registration | `""` |
## Ingress Status
Controls how EasyHAProxy updates Kubernetes Ingress resources with load-balancer IPs.
| Value | Description | Default |
|---|---|---|
| `ingressStatus.enabled` | Update Ingress resources with load-balancer IPs | `true` |
| `ingressStatus.deploymentMode` | How to detect/report IPs: `auto`, `daemonset`, `nodeport`, or `clusterip`. `auto` is recommended. | `auto` |
| `ingressStatus.externalHostname` | Hostname to report in Ingress status (for ClusterIP mode without a LoadBalancer) | `""` |
| `ingressStatus.updateInterval` | Seconds between Ingress status updates | `30` |
## DaemonSet Node Selection
:::note Only applies when `service.create: false`
These values are ignored when running as a Deployment (`service.create: true`).
:::
| Value | Description | Default |
|---|---|---|
| `masterNode.label` | Node label key used for `nodeAffinity` | `easyhaproxy/node` |
| `masterNode.values` | Accepted values for the node label | `["master"]` |
Label the target node before installing:
```bash
kubectl label nodes node-01 "easyhaproxy/node=master"
```
## Standard Kubernetes Fields
| Value | Description | Default |
|---|---|---|
| `podAnnotations` | Annotations added to the EasyHAProxy pod | `{}` |
| `resources` | CPU/memory requests and limits for the pod | `{}` |
| `nodeSelector` | Node selector for pod scheduling | `{}` |
| `tolerations` | Tolerations for pod scheduling | `[]` |
| `affinity` | Affinity rules for pod scheduling | `{}` |
| `podSecurityContext` | Pod-level security context | `{}` |
| `securityContext` | Container-level security context | `{}` |
## Service Account
| Value | Description | Default |
|---|---|---|
| `serviceAccount.create` | Create a dedicated ServiceAccount | `true` |
| `serviceAccount.annotations` | Annotations to add to the ServiceAccount | `{}` |
| `serviceAccount.name` | Name of the ServiceAccount. Auto-generated if empty. | `""` |
## Ingress Class
| Value | Description | Default |
|---|---|---|
| `ingressClass.create` | Create an `IngressClass` resource named `easyhaproxy` | `true` |
| `ingressClass.annotations` | Annotations to add to the IngressClass | `{}` |
----
[Open source ByJG](http://opensource.byjg.com)

75
docs/reference/other.md Normal file
View file

@ -0,0 +1,75 @@
---
sidebar_position: 5
sidebar_label: "Other Configurations"
---
# Other configurations
## Proxy Headers
EasyHAProxy automatically sets standard proxy-awareness headers for all HTTP requests:
| Header | Description | Example Value |
|--------|-------------|---------------|
| X-Forwarded-For | Client IP address | `203.0.113.50` |
| X-Forwarded-Port | Port HAProxy received request on | `443` |
| X-Forwarded-Proto | Protocol (http or https) | `https` |
| X-Forwarded-Host | Original Host header from client | `example.com` |
| X-Request-ID | Unique request identifier (UUID) | `550e8400-e29b-41d4-a716-446655440000` |
These headers help backend applications:
- Determine the original client IP
- Detect HTTPS vs HTTP
- Generate correct URLs with proper hostname
- Correlate requests for debugging and monitoring
**Note:** Headers are only added in HTTP mode, not TCP mode.
## Exposing Ports
Some ports on the EasyHAProxy container and in the firewall are required to be open. However, you don't need to expose the other container ports because EasyHAProxy will handle that.
- The ports `80` and `443`.
- If you enable the HAProxy statistics, you must also expose the port defined in `HAPROXY_STATS_PORT` environment variable (default 1936). Statistics are only generated when you set `HAPROXY_PASSWORD`.
- Every port defined in `easyhaproxy.[definitions].port` also should be exposed.
For example:
```bash title="Expose required ports"
docker run \
/* other parameters */
-p 80:80 \
-p 443:443 \
-p 1936:1936 \
-d byjg/easy-haproxy
```
## Mapping Docker Volume
The docker volume or a way to call the API needs to pass to the EasyHAProxy container.
```bash title="Mount Docker socket"
docker run \
/* other parameters */
-v /var/run/docker.sock:/var/run/docker.sock \
-d byjg/easy-haproxy
```
## Mapping custom .cfg files
You can concatenate valid HAProxy `.cfg` files to the dynamically generated `haproxy.cfg` by mapping the folder `/etc/easyhaproxy/haproxy/conf.d`.
```bash title="Mount custom config directory"
docker run \
/* other parameters */
-v /your/local/conf.d:/etc/easyhaproxy/haproxy/conf.d \
-d byjg/easy-haproxy
```
## Setting Custom Errors
If enabled, map the volume : `/etc/easyhaproxy/haproxy/errors-custom/` to your container and put a file named `ERROR_NUMBER.http`
where ERROR_NUMBER is the HTTP error code (e.g., `503.http`)
----
[Open source ByJG](http://opensource.byjg.com)

View file

@ -0,0 +1,4 @@
{
"label": "Plugins",
"position": 5
}

View file

@ -0,0 +1,80 @@
---
sidebar_position: 6
sidebar_label: "Cleanup"
---
# Cleanup Plugin
**Type:** Global Plugin
**Runs:** Once per discovery cycle
## Overview
The Cleanup plugin performs cleanup tasks during each discovery cycle, such as removing old temporary files.
## Why Use It
Prevents disk space issues by automatically cleaning up temporary files created by EasyHAProxy.
## Configuration Options
| Option | Description | Default |
|----------------------|----------------------------------------------|---------|
| `enabled` | Enable/disable plugin | `true` |
| `max_idle_time` | Maximum age in seconds before deleting files | `300` |
| `cleanup_temp_files` | Enable temp file cleanup | `true` |
## Configuration Examples
### Static YAML Configuration
```yaml
# /etc/easyhaproxy/static/config.yaml
plugins:
enabled: [cleanup]
config:
cleanup:
max_idle_time: 600
cleanup_temp_files: true
```
### Environment Variables
| Environment Variable | Config Key | Type | Default | Description |
|-------------------------------------------------|----------------------|----------|---------|----------------------------------------------|
| `EASYHAPROXY_PLUGINS_ENABLED` | - | string | - | Enable cleanup plugin (value: `cleanup`) |
| `EASYHAPROXY_PLUGIN_CLEANUP_ENABLED` | `enabled` | boolean | `true` | Enable/disable plugin |
| `EASYHAPROXY_PLUGIN_CLEANUP_MAX_IDLE_TIME` | `max_idle_time` | integer | `300` | Maximum age in seconds before deleting files |
| `EASYHAPROXY_PLUGIN_CLEANUP_CLEANUP_TEMP_FILES` | `cleanup_temp_files` | boolean | `true` | Enable temp file cleanup |
### Custom Idle Time (1 hour)
```yaml
plugins:
enabled: [cleanup]
config:
cleanup:
enabled: true
max_idle_time: 3600 # 1 hour
```
## How It Works
The cleanup plugin:
- Runs once during each discovery cycle
- Scans temporary directories for old files
- Removes files older than `max_idle_time` seconds
- Helps maintain disk space efficiency
## Important Notes
- This is a **global plugin** - it runs once per discovery cycle, not per domain
- Does not generate HAProxy configuration
- Performs maintenance operations in the background
- Safe to enable in production environments
## Related Documentation
- [Plugin System Overview](../../guides/plugins.md)
- [Environment Variables Reference](../environment-variables.md)
- [Static Configuration Reference](../../getting-started/static.md)

View file

@ -0,0 +1,120 @@
---
sidebar_position: 3
sidebar_label: "Cloudflare"
---
# Cloudflare Plugin
**Type:** Domain Plugin
**Runs:** Once for each discovered domain/host
## Overview
The Cloudflare plugin restores the original visitor IP address when requests come through Cloudflare's CDN. The plugin includes **built-in Cloudflare IP ranges** that are automatically written to the IP list file - no manual configuration required!
## Why Use It
Cloudflare replaces the visitor's IP with its own. This plugin restores the original IP from the `CF-Connecting-IP` header.
## Configuration Options
| Option | Description | Default |
|-------------------|------------------------------------------|---------------------------------------|
| `enabled` | Enable/disable plugin | `true` |
| `use_builtin_ips` | Use built-in Cloudflare IP ranges | `true` |
| `ip_list_path` | Path to Cloudflare IP list | `/etc/easyhaproxy/cloudflare_ips.lst` |
## Configuration Examples
### Docker/Docker Compose (Basic - Uses Built-in IPs)
```yaml
services:
myapp:
labels:
easyhaproxy.http.host: example.com
easyhaproxy.http.plugins: cloudflare
# Built-in Cloudflare IPs are automatically used - no additional configuration needed!
```
### Docker/Docker Compose (Custom IP List)
```yaml
labels:
easyhaproxy.http.plugins: cloudflare
easyhaproxy.http.plugin.cloudflare.use_builtin_ips: false
easyhaproxy.http.plugin.cloudflare.ip_list_path: /custom/path/cf_ips.lst
```
### Kubernetes Annotations
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
easyhaproxy.plugins: "cloudflare"
easyhaproxy.plugin.cloudflare.ip_list_path: "/etc/easyhaproxy/cloudflare_ips.lst"
spec:
rules:
- host: example.com
http:
paths:
- path: /
backend:
service:
name: myapp
port:
number: 80
```
### Static YAML Configuration
```yaml
plugins:
config:
cloudflare:
enabled: true
use_builtin_ips: true # Uses built-in Cloudflare IPs (default)
```
### Environment Variables
| Environment Variable | Config Key | Type | Default | Description |
|-------------------------------------------------|-------------------|----------|---------------------------------------|---------------------------------------|
| `EASYHAPROXY_PLUGIN_CLOUDFLARE_ENABLED` | `enabled` | boolean | `true` | Enable/disable plugin for all domains |
| `EASYHAPROXY_PLUGIN_CLOUDFLARE_USE_BUILTIN_IPS` | `use_builtin_ips` | boolean | `true` | Use built-in Cloudflare IP ranges |
| `EASYHAPROXY_PLUGIN_CLOUDFLARE_IP_LIST_PATH` | `ip_list_path` | string | `/etc/easyhaproxy/cloudflare_ips.lst` | Path to Cloudflare IP list file |
## Generated HAProxy Configuration
```haproxy
# Cloudflare - Restore original visitor IP
acl from_cloudflare src -f /etc/easyhaproxy/cloudflare_ips.lst
http-request set-header X-Forwarded-For %[req.hdr(CF-Connecting-IP)] if from_cloudflare
```
## Built-in Cloudflare IP Ranges
The plugin includes the current Cloudflare IP ranges (22 ranges total):
**IPv4 Ranges (15):**
- 173.245.48.0/20, 103.21.244.0/22, 103.22.200.0/22, 103.31.4.0/22
- 141.101.64.0/18, 108.162.192.0/18, 190.93.240.0/20, 188.114.96.0/20
- 197.234.240.0/22, 198.41.128.0/17, 162.158.0.0/15, 104.16.0.0/13
- 104.24.0.0/14, 172.64.0.0/13, 131.0.72.0/22
**IPv6 Ranges (7):**
- 2400:cb00::/32, 2606:4700::/32, 2803:f800::/32, 2405:b500::/32
- 2405:8100::/32, 2a06:98c0::/29, 2c0f:f248::/32
## Important Notes
- ✅ **No manual configuration required** - Built-in Cloudflare IPs are included!
- The plugin runs once per domain during the discovery cycle
- IP list file is automatically created and updated
## Related Documentation
- [Plugin System Overview](../../guides/plugins.md)
- [Container Labels Reference](../container-labels.md)

View file

@ -0,0 +1,123 @@
---
sidebar_position: 5
sidebar_label: "Deny Pages"
---
# Deny Pages Plugin
**Type:** Domain Plugin
**Runs:** Once for each discovered domain/host
## Overview
The Deny Pages plugin blocks access to specific paths for a domain, returning a configurable HTTP status code.
## Why Use It
Protect admin panels, internal APIs, or debugging endpoints from public access.
## Configuration Options
| Option | Description | Default |
|---------------|----------------------------------------|------------|
| `enabled` | Enable/disable plugin | `true` |
| `paths` | Comma-separated list of paths to block | (required) |
| `status_code` | HTTP status code to return | `403` |
## Configuration Examples
### Docker/Docker Compose (Basic)
```yaml
services:
webapp:
labels:
easyhaproxy.http.host: example.com
easyhaproxy.http.plugins: deny_pages
easyhaproxy.http.plugin.deny_pages.paths: /admin,/private,/debug
easyhaproxy.http.plugin.deny_pages.status_code: 404
```
### WordPress Protection
```yaml
labels:
easyhaproxy.http.host: wordpress.example.com
easyhaproxy.http.plugins: deny_pages
easyhaproxy.http.plugin.deny_pages.paths: /wp-admin,/wp-login.php,/.env
easyhaproxy.http.plugin.deny_pages.status_code: 404
```
### Kubernetes Annotations
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
easyhaproxy.plugins: "deny_pages"
easyhaproxy.plugin.deny_pages.paths: "/admin,/private"
easyhaproxy.plugin.deny_pages.status_code: "403"
spec:
rules:
- host: example.com
http:
paths:
- path: /
backend:
service:
name: webapp
port:
number: 80
```
### Static YAML Configuration
```yaml
containers:
"example.com:80":
ip: ["webapp:80"]
plugins: [deny_pages]
plugin:
deny_pages:
paths: [/admin, /private, /debug]
status_code: 403
```
### Multiple Plugins (with Cloudflare)
```yaml
labels:
easyhaproxy.http.host: secure-app.com
easyhaproxy.http.plugins: cloudflare,deny_pages
easyhaproxy.http.plugin.deny_pages.paths: /admin,/config
easyhaproxy.http.plugin.deny_pages.status_code: 403
```
### Environment Variables
| Environment Variable | Config Key | Type | Default | Description |
|---------------------------------------------|---------------|---------|---------|----------------------------------------|
| `EASYHAPROXY_PLUGIN_DENY_PAGES_ENABLED` | `enabled` | boolean | `true` | Enable/disable plugin for all domains |
| `EASYHAPROXY_PLUGIN_DENY_PAGES_PATHS` | `paths` | string | - | Comma-separated list of paths to block |
| `EASYHAPROXY_PLUGIN_DENY_PAGES_STATUS_CODE` | `status_code` | integer | `403` | HTTP status code to return |
## Generated HAProxy Configuration
```haproxy
# Deny Pages - Block specific paths
acl denied_path path_beg /admin /private /debug
http-request deny deny_status 404 if denied_path
```
## Important Notes
- The plugin runs once per domain during the discovery cycle
- Path matching uses `path_beg` (prefix matching), so `/admin` blocks `/admin/*` too
- Consider using `404` instead of `403` to hide the existence of blocked paths
- Works well in combination with other security plugins
## Related Documentation
- [Plugin System Overview](../../guides/plugins.md)
- [Container Labels Reference](../container-labels.md)

View file

@ -0,0 +1,156 @@
---
sidebar_position: 2
sidebar_label: "FastCGI"
---
# FastCGI Plugin
**Type:** Domain Plugin
**Runs:** Once for each discovered domain/host
## Overview
The FastCGI plugin configures HAProxy to communicate with PHP-FPM and other FastCGI applications. It automatically generates the necessary HAProxy `fcgi-app` configuration that defines CGI parameters for proper PHP-FPM communication.
## Why Use It
Automatically generates HAProxy `fcgi-app` configuration that defines required CGI parameters for PHP-FPM communication without manual HAProxy configuration.
## Configuration Options
| Option | Description | Default |
|-------------------|-----------------------------------------|------------------------------------|
| `enabled` | Enable/disable plugin | `true` |
| `document_root` | Document root path | `/etc/easyhaproxy/www` |
| `script_filename` | Custom pattern for SCRIPT_FILENAME | `%[path]` (uses HAProxy's default) |
| `index_file` | Default index file | `index.php` |
| `path_info` | Enable PATH_INFO support | `true` |
| `custom_params` | Dictionary of custom FastCGI parameters | (optional) |
## Configuration Examples
### Docker/Docker Compose (TCP connection)
```yaml
services:
php-fpm:
image: php:8.2-fpm
labels:
easyhaproxy.http.host: phpapp.local
easyhaproxy.http.port: 80
easyhaproxy.http.localport: 9000
easyhaproxy.http.proto: fcgi
easyhaproxy.http.plugins: fastcgi
easyhaproxy.http.plugin.fastcgi.document_root: /etc/easyhaproxy/www
easyhaproxy.http.plugin.fastcgi.index_file: index.php
volumes:
- ./app:/etc/easyhaproxy/www
```
### Docker/Docker Compose (Unix socket)
```yaml
services:
php-fpm:
image: php:8.2-fpm
labels:
easyhaproxy.http.host: phpapp.local
easyhaproxy.http.socket: /run/php/php-fpm.sock
easyhaproxy.http.proto: fcgi
easyhaproxy.http.plugins: fastcgi
easyhaproxy.http.plugin.fastcgi.document_root: /etc/easyhaproxy/www
easyhaproxy.http.plugin.fastcgi.index_file: index.php
volumes:
- ./app:/etc/easyhaproxy/www
- /run/php:/run/php
```
### Kubernetes Annotations
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
easyhaproxy.plugins: "fastcgi"
easyhaproxy.plugin.fastcgi.document_root: "/etc/easyhaproxy/www"
easyhaproxy.plugin.fastcgi.index_file: "index.php"
spec:
rules:
- host: phpapp.example.com
http:
paths:
- path: /
backend:
service:
name: php-fpm
port:
number: 9000
```
### Static YAML Configuration
```yaml
# /etc/easyhaproxy/static/config.yaml
easymapping:
- host: phpapp.local
port: 80
container: php-fpm:9000
proto: fcgi
plugins:
- fastcgi
plugin_config:
fastcgi:
document_root: /etc/easyhaproxy/www
index_file: index.php
path_info: true
```
### Environment Variables
| Environment Variable | Config Key | Type | Default | Description |
|----------------------------------------------|-------------------|----------|------------------------|---------------------------------------|
| `EASYHAPROXY_PLUGIN_FASTCGI_ENABLED` | `enabled` | boolean | `true` | Enable/disable plugin for all domains |
| `EASYHAPROXY_PLUGIN_FASTCGI_DOCUMENT_ROOT` | `document_root` | string | `/etc/easyhaproxy/www` | Document root path |
| `EASYHAPROXY_PLUGIN_FASTCGI_SCRIPT_FILENAME` | `script_filename` | string | `%[path]` | Custom pattern for SCRIPT_FILENAME |
| `EASYHAPROXY_PLUGIN_FASTCGI_INDEX_FILE` | `index_file` | string | `index.php` | Default index file |
| `EASYHAPROXY_PLUGIN_FASTCGI_PATH_INFO` | `path_info` | boolean | `true` | Enable PATH_INFO support |
## Generated HAProxy Configuration
```haproxy
# Top-level fcgi-app definition (added after defaults, before frontends/backends)
fcgi-app fcgi_phpapp_local
docroot /etc/easyhaproxy/www
index index.php
path-info ^(/.+\.php)(/.*)?$
# Backend configuration (added to the backend section)
backend srv_phpapp_local_80
use-fcgi-app fcgi_phpapp_local
server srv-0 172.19.0.3:9000 proto fcgi
```
## CGI Parameters
The plugin configures:
- ✅ **SCRIPT_FILENAME** - Path to PHP script
- ✅ **DOCUMENT_ROOT** - Document root directory
- ✅ **SCRIPT_NAME** - Script name from URL
- ✅ **REQUEST_URI** - Full request URI with query string
- ✅ **QUERY_STRING** - URL query parameters
- ✅ **REQUEST_METHOD** - HTTP method (GET, POST, etc.)
- ✅ **CONTENT_TYPE & CONTENT_LENGTH** - Request body info
- ✅ **SERVER_NAME & SERVER_PORT** - Server details
- ✅ **HTTPS** - SSL/TLS status
- ✅ **PATH_INFO** - Path information (optional)
## Important Notes
- **Required:** Use this plugin together with `proto: fcgi` parameter for complete PHP-FPM support
- The plugin runs once per domain during the discovery cycle
## Related Documentation
- [Plugin System Overview](../../guides/plugins.md)
- [Container Labels Reference](../container-labels.md)

View file

@ -0,0 +1,121 @@
---
sidebar_position: 4
sidebar_label: "IP Whitelist"
---
# IP Whitelist Plugin
**Type:** Domain Plugin
**Runs:** Once for each discovered domain/host
## Overview
The IP Whitelist plugin restricts access to a domain to only specific IP addresses or CIDR ranges.
## Why Use It
Restrict access to internal tools, admin panels, or staging environments to only trusted IP addresses.
## Configuration Options
| Option | Description | Default |
|---------------|--------------------------------------------------|------------|
| `enabled` | Enable/disable plugin | `true` |
| `allowed_ips` | Comma-separated list of IPs/CIDR ranges to allow | (required) |
| `status_code` | HTTP status code to return for blocked IPs | `403` |
## Configuration Examples
### Docker/Docker Compose (Basic)
```yaml
services:
admin:
labels:
easyhaproxy.http.host: admin.example.com
easyhaproxy.http.plugins: ip_whitelist
easyhaproxy.http.plugin.ip_whitelist.allowed_ips: 192.168.1.0/24,10.0.0.5
easyhaproxy.http.plugin.ip_whitelist.status_code: 403
```
### Office Network Access
```yaml
labels:
easyhaproxy.http.host: admin.example.com
easyhaproxy.http.plugins: ip_whitelist
easyhaproxy.http.plugin.ip_whitelist.allowed_ips: 203.0.113.0/24,198.51.100.42
```
### Kubernetes Annotations
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
easyhaproxy.plugins: "ip_whitelist"
easyhaproxy.plugin.ip_whitelist.allowed_ips: "192.168.1.0/24,10.0.0.5"
easyhaproxy.plugin.ip_whitelist.status_code: "403"
spec:
rules:
- host: admin.example.com
http:
paths:
- path: /
backend:
service:
name: admin-panel
port:
number: 80
```
### Static YAML Configuration
```yaml
easymapping:
- host: admin.example.com
port: 443
container: admin-panel:443
plugins:
- ip_whitelist
plugin_config:
ip_whitelist:
allowed_ips: 192.168.1.0/24,10.0.0.5
status_code: 403
```
### Environment Variables
| Environment Variable | Config Key | Type | Default | Description |
|-----------------------------------------------|---------------|----------|---------|--------------------------------------------------|
| `EASYHAPROXY_PLUGIN_IP_WHITELIST_ENABLED` | `enabled` | boolean | `true` | Enable/disable plugin for all domains |
| `EASYHAPROXY_PLUGIN_IP_WHITELIST_ALLOWED_IPS` | `allowed_ips` | string | - | Comma-separated list of IPs/CIDR ranges to allow |
| `EASYHAPROXY_PLUGIN_IP_WHITELIST_STATUS_CODE` | `status_code` | integer | `403` | HTTP status code to return for blocked IPs |
## Generated HAProxy Configuration
```haproxy
# IP Whitelist - Only allow specific IPs
acl whitelisted_ip src 192.168.1.0/24 10.0.0.5
http-request deny deny_status 403 if !whitelisted_ip
```
## IP Address Formats
The plugin supports:
- **Single IPs:** `10.0.0.5`, `203.0.113.42`
- **CIDR ranges:** `192.168.1.0/24`, `10.0.0.0/8`
- **Multiple entries:** Comma-separated list of IPs and/or CIDR ranges
## Important Notes
- **Warning:** This blocks ALL IPs except those in the whitelist. Make sure to include your own IP!
- The plugin runs once per domain during the discovery cycle
- Test thoroughly before deploying to production
- Consider using VPN CIDR ranges for remote access
## Related Documentation
- [Plugin System Overview](../../guides/plugins.md)
- [Container Labels Reference](../container-labels.md)

View file

@ -0,0 +1,196 @@
---
sidebar_position: 1
sidebar_label: "JWT Validator"
---
# JWT Validator Plugin
**Type:** Domain Plugin
**Runs:** Once for each discovered domain/host
## Overview
The JWT Validator plugin validates JWT (JSON Web Token) authentication tokens using HAProxy's built-in JWT functionality.
## Why Use It
Protect APIs and services with JWT authentication without needing application-level code.
## Generating JWT Keys
```bash
# Generate RSA key pair (idempotent - skips if exists)
[ -f jwt_private.pem ] || openssl genrsa -out jwt_private.pem 2048
[ -f jwt_pubkey.pem ] || openssl rsa -in jwt_private.pem -pubout -out jwt_pubkey.pem
```
## Configuration Options
| Option | Description | Default |
|-------------------|----------------------------------------------------------------------------------------------|-------------|
| `enabled` | Enable/disable plugin | `true` |
| `algorithm` | JWT signing algorithm | `RS256` |
| `issuer` | Expected JWT issuer (optional, set to `none`/`null` to skip validation) | (optional) |
| `audience` | Expected JWT audience (optional, set to `none`/`null` to skip validation) | (optional) |
| `pubkey_path` | Path to public key file (priority 1: explicit file path) | (optional) |
| `pubkey` | Public key content as base64-encoded string (priority 2: inline content) | (optional) |
| `k8s_secret.pubkey` | Kubernetes secret containing public key (priority 3: Kubernetes only) | (optional) |
| `paths` | List of paths that require JWT validation (optional) | (all paths) |
| `only_paths` | If `true`, only specified paths are accessible; if `false`, only specified paths require JWT | `false` |
| `allow_anonymous` | If `true`, allows requests without Authorization header (validates JWT if present) | `false` |
### Public Key Configuration Priority
When multiple public key options are configured, they are evaluated in this order:
1. **`pubkey_path`** - Direct file path (explicit configuration)
2. **`pubkey`** - Base64-encoded key content (inline configuration)
3. **`k8s_secret.pubkey`** - Kubernetes secret (recommended for Kubernetes deployments)
## Path Validation Logic
- **No paths configured:** ALL requests to the domain require JWT validation (default behavior)
- **Paths configured + `only_paths=false`:** Only specified paths require JWT validation, other paths pass through without validation
- **Paths configured + `only_paths=true`:** Only specified paths are accessible (with JWT validation), all other paths are denied
## Anonymous Access Logic
- **`allow_anonymous=false` (default):** Requests without `Authorization` header are denied
- **`allow_anonymous=true`:** Requests without `Authorization` header are allowed to pass through, but JWTs are validated if the header is present
## Configuration Examples
### Docker/Docker Compose (Protect All Paths)
```yaml
services:
api:
labels:
easyhaproxy.http.host: api.example.com
easyhaproxy.http.plugins: jwt_validator
easyhaproxy.http.plugin.jwt_validator.algorithm: RS256
easyhaproxy.http.plugin.jwt_validator.issuer: https://auth.example.com/
easyhaproxy.http.plugin.jwt_validator.audience: https://api.example.com
easyhaproxy.http.plugin.jwt_validator.pubkey_path: /etc/easyhaproxy/jwt_keys/api_pubkey.pem
volumes:
- ./pubkey.pem:/etc/easyhaproxy/jwt_keys/api_pubkey.pem:ro
```
### Protect Specific Paths Only
```yaml
labels:
easyhaproxy.http.plugins: jwt_validator
easyhaproxy.http.plugin.jwt_validator.pubkey_path: /etc/easyhaproxy/jwt_keys/api_pubkey.pem
easyhaproxy.http.plugin.jwt_validator.paths: /api/admin,/api/sensitive
easyhaproxy.http.plugin.jwt_validator.only_paths: false
# /api/health, /api/docs, etc. remain publicly accessible
```
### Only Allow Specific Paths
```yaml
labels:
easyhaproxy.http.plugins: jwt_validator
easyhaproxy.http.plugin.jwt_validator.pubkey_path: /etc/easyhaproxy/jwt_keys/api_pubkey.pem
easyhaproxy.http.plugin.jwt_validator.paths: /api/public,/api/v1
easyhaproxy.http.plugin.jwt_validator.only_paths: true
# All paths except /api/public and /api/v1 are denied
```
### Kubernetes with Secrets (Recommended)
```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"
easyhaproxy.plugin.jwt_validator.paths: "/api/admin,/api/users"
easyhaproxy.plugin.jwt_validator.only_paths: "false"
spec:
ingressClassName: easyhaproxy
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
```
### Static YAML Configuration
```yaml
# /etc/easyhaproxy/static/config.yaml
containers:
"api.example.com:443":
ip: ["api-service:8080"]
ssl: true
plugins: [jwt_validator]
plugin:
jwt_validator:
algorithm: RS256
issuer: https://auth.example.com/
audience: https://api.example.com
pubkey_path: /etc/easyhaproxy/jwt_keys/api_pubkey.pem
```
### Environment Variables
| Environment Variable | Config Key | Type | Default | Description |
|----------------------------------------------------|-------------------|---------|---------|---------------------------------------------|
| `EASYHAPROXY_PLUGIN_JWT_VALIDATOR_ENABLED` | `enabled` | boolean | `true` | Enable/disable plugin for all domains |
| `EASYHAPROXY_PLUGIN_JWT_VALIDATOR_ALGORITHM` | `algorithm` | string | `RS256` | JWT signing algorithm |
| `EASYHAPROXY_PLUGIN_JWT_VALIDATOR_ISSUER` | `issuer` | string | - | Expected JWT issuer (optional) |
| `EASYHAPROXY_PLUGIN_JWT_VALIDATOR_AUDIENCE` | `audience` | string | - | Expected JWT audience (optional) |
| `EASYHAPROXY_PLUGIN_JWT_VALIDATOR_PUBKEY_PATH` | `pubkey_path` | string | - | Path to public key file |
| `EASYHAPROXY_PLUGIN_JWT_VALIDATOR_PUBKEY` | `pubkey` | string | - | Public key as base64-encoded string |
| `EASYHAPROXY_PLUGIN_JWT_VALIDATOR_PATHS` | `paths` | string | - | Comma-separated paths requiring JWT |
| `EASYHAPROXY_PLUGIN_JWT_VALIDATOR_ONLY_PATHS` | `only_paths` | boolean | `false` | If true, only specified paths accessible |
| `EASYHAPROXY_PLUGIN_JWT_VALIDATOR_ALLOW_ANONYMOUS` | `allow_anonymous` | boolean | `false` | Allow requests without Authorization header |
## What It Validates
- ✅ Authorization header presence
- ✅ JWT signing algorithm (RS256, RS512, etc.)
- ✅ JWT issuer (if configured)
- ✅ JWT audience (if configured)
- ✅ JWT signature using public key
- ✅ JWT expiration time
## Important Notes
- **Required:** HAProxy 2.5+ with JWT support
- Mount public key file as read-only volume
- The plugin runs once per domain during the discovery cycle
- Test thoroughly with your JWT provider before deploying to production
## Related Documentation
- [Plugin System Overview](../../guides/plugins.md)
- [Container Labels Reference](../container-labels.md)
- [Kubernetes Secrets](../../getting-started/kubernetes.md#loading-plugin-configuration-from-kubernetes-secrets)

199
docs/reference/volumes.md Normal file
View file

@ -0,0 +1,199 @@
---
sidebar_position: 4
sidebar_label: "Volumes"
---
# Volumes
:::info Volume Mapping
These volumes allow you to persist certificates, provide custom configurations, and extend EasyHAProxy functionality.
:::
## Directory Structure
:::info Base Path
All EasyHAProxy files are organized under `/etc/easyhaproxy/`. This can be customized using the `EASYHAPROXY_BASE_PATH` environment variable.
:::
```plaintext title="/etc/easyhaproxy/ Directory Tree"
/etc/easyhaproxy/
├── static/ # 🔧 Runtime (static mode only)
│ └── config.yml # Static service configuration
├── haproxy/
│ ├── haproxy.cfg # 🔧 Runtime - Generated HAProxy config
│ ├── conf.d/ # 📦 Base image
│ │ ├── README.md
│ │ └── *.cfg # User-provided custom configs
│ └── errors-custom/ # 📦 Base image
│ ├── 400.http # Bad Request
│ ├── 403.http # Forbidden
│ ├── 408.http # Request Timeout
│ ├── 500.http # Internal Server Error
│ ├── 502.http # Bad Gateway
│ ├── 503.http # Service Unavailable
│ └── 504.http # Gateway Timeout
├── certs/
│ ├── live/ # 🔧 Runtime (Certbot)
│ │ └── {domain}/
│ │ ├── cert.pem # Certificate only
│ │ ├── chain.pem # Certificate chain
│ │ ├── fullchain.pem # cert.pem + chain.pem
│ │ ├── privkey.pem # Private key
│ │ └── README
│ ├── archive/ # 🔧 Runtime (Certbot)
│ │ └── {domain}/
│ │ ├── cert1.pem, cert2.pem... # Versioned certificates
│ │ └── privkey1.pem... # Versioned keys
│ ├── work/ # 🔧 Runtime (Certbot working dir)
│ ├── logs/ # 🔧 Runtime (Certbot logs)
│ │ └── letsencrypt.log
│ ├── certbot/ # 📦 Base image
│ │ ├── {domain}.pem # 🔧 Runtime - Merged cert+key
│ │ └── placeholder.pem # 📦 Base image - Placeholder cert
│ └── haproxy/ # 📦 Base image
│ ├── {domain}.pem # User-provided cert+key (PEM format)
│ └── placeholder.pem # 📦 Base image - Placeholder cert
├── plugins/ # Optional - Custom plugins
│ └── *.py # Python plugin files
├── jwt_keys/ # Optional - JWT validation
│ └── *.pem # RSA public keys
├── cloudflare_ips.lst # Optional - Cloudflare plugin
└── www/ # Optional - FastCGI document root
└── index.php
```
:::tip Legend
- **📦 Base image** - Included in the Docker image
- **🔧 Runtime** - Created/generated when EasyHAProxy runs
- **Optional** - Created only when specific features are used
:::
## Common Volume Mappings
The most commonly mapped volumes for persistence and customization:
| Volume | Purpose | Required |
|-------------------------------------------|-------------------------------------------------------------------------------------------------------|----------|
| `/etc/easyhaproxy/static/` | [Static configuration](../getting-started/static.md) - mount your `config.yml` here | Optional |
| `/etc/easyhaproxy/certs/haproxy/` | [SSL certificates](../guides/ssl.md) - user-provided certificates in PEM format | Optional |
| `/etc/easyhaproxy/certs/certbot/` | [ACME/Certbot certificates](../guides/acme.md) - auto-generated Let's Encrypt certificates | Optional |
| `/etc/easyhaproxy/certs/live/` | Certbot live certificates - persist across container restarts | Optional |
| `/etc/easyhaproxy/haproxy/conf.d/` | [Custom HAProxy config](other.md) - additional `.cfg` files to include | Optional |
| `/etc/easyhaproxy/haproxy/errors-custom/` | [Custom error pages](other.md) - custom HTTP error pages (400, 403, 500, etc.) | Optional |
| `/etc/easyhaproxy/plugins/` | [Custom plugins](../guides/plugins.md) - Python plugin files | Optional |
| `/etc/easyhaproxy/jwt_keys/` | [JWT public keys](plugins/jwt-validator.md) - RSA public keys for JWT validation | Optional |
| `/etc/easyhaproxy/www/` | [FastCGI document root](plugins/fastcgi.md) - PHP/FastCGI application files | Optional |
## Directory Details
### Configuration Files
#### Static Configuration
```bash
/etc/easyhaproxy/static/config.yml
```
Static service configuration when not using service discovery (Docker/Kubernetes).
:::note
This directory only exists when `EASYHAPROXY_DISCOVER=static` is set.
:::
#### HAProxy Configuration
```bash
/etc/easyhaproxy/haproxy/haproxy.cfg
```
Auto-generated HAProxy configuration file.
:::warning Do Not Edit
This file is automatically generated by EasyHAProxy. Any manual changes will be overwritten.
:::
#### Custom Configuration Snippets
```bash
/etc/easyhaproxy/haproxy/conf.d/*.cfg
```
Place custom HAProxy configuration snippets here. These files are automatically included in the main configuration.
:::tip Example
```bash
# Mount your custom config
docker run -v ./my-custom.cfg:/etc/easyhaproxy/haproxy/conf.d/my-custom.cfg byjg/easy-haproxy
```
:::
### SSL/TLS Certificates
#### User-Provided Certificates
```bash
/etc/easyhaproxy/certs/haproxy/{domain}.pem
```
Place your SSL certificates here in PEM format (certificate + private key combined).
:::info PEM Format
```bash
cat domain.crt domain.key > /etc/easyhaproxy/certs/haproxy/domain.com.pem
```
:::
#### ACME/Let's Encrypt Certificates
```bash
/etc/easyhaproxy/certs/certbot/{domain}.pem # Merged cert+key for HAProxy
/etc/easyhaproxy/certs/live/{domain}/ # Certbot live certificates (symlinks)
/etc/easyhaproxy/certs/archive/{domain}/ # Versioned certificate archive
```
EasyHAProxy automatically merges Certbot certificates from `/etc/easyhaproxy/certs/live/` into `/etc/easyhaproxy/certs/certbot/` for HAProxy consumption.
:::tip Persist Certbot Certificates
```yaml
volumes:
- certbot-certs:/etc/easyhaproxy/certs/live
- certbot-archive:/etc/easyhaproxy/certs/archive
```
:::
### Plugins & Extensions
#### Custom Plugins
```bash
/etc/easyhaproxy/plugins/*.py
```
Add custom Python plugins to extend EasyHAProxy functionality.
See [Plugin Development](../guides/plugin-development.md) for details.
#### JWT Public Keys
```bash
/etc/easyhaproxy/jwt_keys/*.pem
```
RSA public keys for [JWT token validation](plugins/jwt-validator.md).
#### Cloudflare IP Ranges
```bash
/etc/easyhaproxy/cloudflare_ips.lst
```
Cloudflare IP ranges for the [Cloudflare plugin](plugins/cloudflare.md) to restore real client IPs.
### Error Pages
```bash
/etc/easyhaproxy/haproxy/errors-custom/{code}.http
```
Custom HTTP error pages (400, 403, 408, 500, 502, 503, 504). Default error pages are included in the base image.
:::tip Customize Error Pages
```bash
# Mount your custom 503 error page
docker run -v ./custom-503.http:/etc/easyhaproxy/haproxy/errors-custom/503.http byjg/easy-haproxy
```
:::
----
[Open source ByJG](http://opensource.byjg.com)