Unreleased documentation. Choose your installed release in the version menu. Features described here may be absent from that release.
Deploying with Helm¶
Install HAPTIC with the Helm chart. It deploys the controller, two HAProxy replicas, custom resource definitions (CRDs), and the template libraries for Ingress and Gateway API. Configure the installation through Helm values. For a first installation and an optional sample route, follow Getting started.
Prerequisites¶
- Kubernetes 1.35 or newer; see Kubernetes compatibility checks
- Helm 3.8 or newer
Note
Set haproxyVersion to select matching controller and HAProxy images. The default is 3.4; see HAProxy versions for supported alternatives.
Installation¶
helm install haptic oci://ghcr.io/haproxy-haptic/haptic/charts/haptic \
--version 0.9.0 --namespace haptic --create-namespace
With custom values:
helm install haptic oci://ghcr.io/haproxy-haptic/haptic/charts/haptic \
--version 0.9.0 --namespace haptic --create-namespace \
-f haptic-values.yaml
Check the installation¶
Wait for the controller and HAProxy Deployments to become ready:
kubectl rollout status deployment/haptic-controller --namespace haptic --timeout=180s
kubectl rollout status deployment/haptic-haproxy --namespace haptic --timeout=180s
These names use the release and namespace from the install command. For a failed rollout, follow installation troubleshooting.
Change settings¶
Keep your custom settings in haptic-values.yaml. Add the values shown in these
guides to that file, then pass the complete file when you install or upgrade.
If you already have a values file for this release, use it. If you don't, export the values from your installed release before making changes:
helm get values haptic --namespace haptic --output yaml > haptic-values.yaml
if [ "$(cat haptic-values.yaml)" = null ]; then
printf '{}\n' > haptic-values.yaml
fi
This includes settings supplied with --set. Keep them when adding a new setting;
passing only the new setting to helm upgrade can restore other settings to their
chart defaults. Use the upgrade command to apply the edited file.
The chart manages the controller, HAProxy pods, configuration, permissions, and validation hooks. See HAProxy deployment settings to change the pod and Service settings, or the values reference for all options.
Running multiple HAPTIC instances in one cluster¶
The example below gives a second HAPTIC release its own namespace, classes, and controller identifiers. This separates its configuration and HAProxy fleet from the first installation:
| Setting | Values key | Purpose |
|---|---|---|
| Release name and namespace | helm install <name> --namespace <ns> |
Separates workloads, configuration, Secrets, and the leader-election lease |
| Ingress class | ingressClass.name |
The controller watches only Ingresses whose spec.ingressClassName equals this value. Two releases sharing it would both process the same Ingresses |
| Gateway class | gatewayClass.name |
The controller watches only Gateways whose spec.gatewayClassName equals this value |
| Controller identifier | ingressClass.controllerName and gatewayClass.controllerName |
The GatewayClass watch is filtered to spec.controllerName; two releases sharing it would fight over the same GatewayClasses' status. Default: haproxy-haptic.org/controller |
The chart derives watch filters from ingressClass.name and gatewayClass.name.
Set the class names in values; the chart updates the filters to match.
The leader-election lease name defaults to the release's full name. The
configuration name defaults to haptic-config, independently of the release name.
If you place releases in the same namespace, give each a distinct
controller.configName and ensure they don't share managed Secrets. Separate
namespaces avoid those ownership conflicts.
Example values for a second release with its own classes:
# team-b-values.yaml
ingressClass:
name: haptic-team-b
controllerName: haproxy-haptic.org/team-b
gatewayClass:
name: haptic-team-b
controllerName: haproxy-haptic.org/team-b
helm install haptic-team-b oci://ghcr.io/haproxy-haptic/haptic/charts/haptic \
--version 0.9.0 \
--namespace haptic-team-b --create-namespace \
-f team-b-values.yaml
Ingress and Gateway authors then select this release with ingressClassName: haptic-team-b or gatewayClassName: haptic-team-b.
Upgrading¶
For an upgrade from 0.5, follow the 0.6 upgrade notes. For an upgrade from 0.3, follow the 0.4 upgrade notes. For an upgrade from 0.2, follow the 0.3 upgrade notes. For an upgrade from 0.1.0 or a 0.2.0 alpha, read the 0.2 upgrade notes first.
Pass your complete values file when upgrading. If you configured the release with
--set and have no saved file, export its values first:
helm upgrade haptic oci://ghcr.io/haproxy-haptic/haptic/charts/haptic \
--version 0.9.0 --namespace haptic \
-f haptic-values.yaml
For an installation with no custom settings, you can upgrade without a values file:
helm upgrade haptic oci://ghcr.io/haproxy-haptic/haptic/charts/haptic \
--version 0.9.0 --namespace haptic
Check the Deployments after an upgrade.
The chart owns the HAProxyTemplateConfig
Put persistent configuration changes under controller.config in your values file. Edits made with kubectl edit or kubectl patch take effect immediately, but a later helm upgrade can overwrite them. Helm also owns the library objects it creates.
Controller preparation¶
After validating the complete incoming configuration, the pre-upgrade hook checks
whether the new binary can load the current configuration. If it can, the hook
updates the existing controller image and waits for the old replicas to exit
before Helm applies new templates. Config and library identities stay unchanged.
The hook preserves your Deployment strategy: Recreate still permits controller
downtime; HAProxy keeps its loaded configuration.
If the live configuration is invalid or a referenced library is missing, the hook reports that it's using the startup recovery path. The validated incoming set is then applied, and each controller must pass its normal startup gate. An API failure, a partially applied library revision, or a changed source stops preparation instead of selecting recovery.
Use a new image tag or digest for each controller build. If an unchanged image reference resolves to a different build, preparation stops before changing the Deployment. Paused Deployments must be resumed before preparation. With zero replicas, the hook waits for existing pods to disappear; the final Deployment starts against the new configuration.
The hook reads immutable build metadata directly from each controller Pod's
/build health endpoint. The shipped NetworkPolicy allows this traffic from the
preflight Pod in the same namespace. If you restrict health-port ingress, allow
the preflight Pod to reach that port. The hook's namespace Role grants read access
to the config, libraries, and workload identities, plus patch access to this
release's controller Deployment. /debug/* remains loopback-only.
Flux HelmRelease runs this Helm hook; Argo CD maps it to PreSync. Applying
rendered manifests directly or using --no-hooks skips preparation. Those paths
retain the startup and live validation gates, but old replicas can reject newer
templates until their replacements start. For release haptic in namespace haptic, run this command in the target
controller image, with cluster credentials, access to controller Pod IPs, and your complete values.yaml,
before applying the rendered manifests:
The Job's preRolloutValidation.activeDeadlineSeconds bounds validation and
preparation together. Increase that configured budget when your chosen
minReadySeconds or rollout size requires more time; the Helm timeout must also
cover the complete operation.
A failed preparation doesn't apply the incoming templates. Some replicas may already use the new image with the previous configuration. Correct the reported cause and retry the upgrade, or roll back the release. Rollback to a chart that predates preparation uses that chart's hooks and can produce temporary template rejections; the startup and live gates still prevent invalid configurations from reaching HAProxy.
Recover a failed upgrade¶
Check the release status and validation Job for the default installation:
helm status haptic --namespace haptic
kubectl get jobs --namespace haptic
kubectl logs --namespace haptic job/haptic-haptic-pre-rollout
If pre-rollout validation fails, fix the reported values or templates and repeat the upgrade command with your complete values file. Existing HAProxy workers keep their last configuration while this check blocks rollout. Earlier hooks may already have updated CRDs or certificates; a failed upgrade doesn't mean every resource is unchanged.
If validation passed but a Deployment doesn't become ready, follow installation troubleshooting. Keep hooks and validation enabled when retrying.
Helm rollback doesn't reverse CRD changes or run the chart's pre-upgrade validation. HAPTIC doesn't guarantee downgrades across configuration API changes. Recover with corrected values or a corrected forward release, and check the upgrade notes for version-specific migrations.
Uninstalling¶
Use the release name and namespace from installation. Uninstall removes the release workloads and configuration. CRDs, retained default-certificate Secrets, and runtime-created agent certificate Secrets remain. Keep the agent issuer and identity Secrets together if you plan to reuse them on reinstall.
Delete the CRDs only when no HAPTIC installation still needs them. This deletes every instance of these resources across all namespaces, including route policies and custom configurations:
kubectl delete crd \
haproxytemplateconfigs.haproxy-haptic.org \
haproxytemplatelibraries.haproxy-haptic.org \
haproxycfgs.haproxy-haptic.org \
haproxygeneralfiles.haproxy-haptic.org \
haproxycrtlistfiles.haproxy-haptic.org \
haproxymapfiles.haproxy-haptic.org \
haproxyroutepolicies.haproxy-haptic.org
Where to go next¶
- Route traffic to your applications.
- Configure HAProxy pods and access, including replicas and Service type.
- Validate a change before rollout.
- Set up monitoring and high availability.