diff --git a/README.md b/README.md index 47131ae..b5bacbd 100644 --- a/README.md +++ b/README.md @@ -44,9 +44,9 @@ Install using tools: | Section | Description | |---------|-------------| -| **[Getting Started](docs/getting-started/index.md)** | Choose your runtime and discovery mode, minimal working setup | +| **[Getting Started](docs/getting-started/)** | Choose your runtime and discovery mode, minimal working setup | | **[Guides](docs/guides/ssl.md)** | SSL, ACME, plugins, Helm, MicroK8s, Dokku, DigitalOcean | -| **[Concepts](docs/concepts/index.md)** | Service discovery, config pipeline, plugin model, TLS termination | +| **[Concepts](docs/concepts/)** | Service discovery, config pipeline, plugin model, TLS termination | | **[Reference](docs/reference/environment-variables.md)** | Environment variables, container labels, CLI flags, volumes | ## Who is using? diff --git a/docs/getting-started/index.md b/docs/getting-started/index.md index 614bf78..43ab0da 100644 --- a/docs/getting-started/index.md +++ b/docs/getting-started/index.md @@ -47,5 +47,5 @@ Pick the guide that matches your environment: 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 +- **[Concepts](../concepts/)** — how service discovery and the config pipeline work - **[Reference](../reference/environment-variables.md)** — full environment variable and label tables diff --git a/docs/reference/environment-variables.md b/docs/reference/environment-variables.md index 7c728bf..4e6026d 100644 --- a/docs/reference/environment-variables.md +++ b/docs/reference/environment-variables.md @@ -34,12 +34,12 @@ For ACME/Certbot configuration (Let's Encrypt, ZeroSSL, etc.), see the [ACME doc 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` | +| 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. diff --git a/docs/reference/helm.md b/docs/reference/helm.md index d48d1bb..9e85e2b 100644 --- a/docs/reference/helm.md +++ b/docs/reference/helm.md @@ -9,25 +9,25 @@ Complete reference for all configurable values in the `byjg/easyhaproxy` Helm ch ## 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 | `""` | +| 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 | `{}` | +| 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. @@ -35,37 +35,37 @@ Set `service.create: true` and `service.type: NodePort` for most setups. DaemonS ## 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 | `[]` | +| 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 | `""` | +| 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` | +| 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 @@ -73,10 +73,10 @@ Controls how EasyHAProxy updates Kubernetes Ingress resources with load-balancer 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"]` | +| 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: @@ -86,30 +86,30 @@ 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 | `{}` | +| 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. | `""` | +| 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 | `{}` | +| 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) diff --git a/docs/reference/other.md b/docs/reference/other.md index 9382146..3b3767d 100644 --- a/docs/reference/other.md +++ b/docs/reference/other.md @@ -9,13 +9,13 @@ sidebar_label: "Other Configurations" 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` | +| 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 diff --git a/docs/reference/plugins/jwt-validator.md b/docs/reference/plugins/jwt-validator.md index e442b26..b3f077f 100644 --- a/docs/reference/plugins/jwt-validator.md +++ b/docs/reference/plugins/jwt-validator.md @@ -26,18 +26,18 @@ Protect APIs and services with JWT authentication without needing application-le ## 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` | +| 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 diff --git a/docs/reference/volumes.md b/docs/reference/volumes.md index 24de2ba..35b0121 100644 --- a/docs/reference/volumes.md +++ b/docs/reference/volumes.md @@ -78,17 +78,17 @@ All EasyHAProxy files are organized under `/etc/easyhaproxy/`. This can be custo 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 | +| 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