Skip to main content

Ingress and TLS

Ingress is off by default, because a first install shouldn’t need DNS. Once you want real hostnames, the chart renders three Ingress objects for you.

Supported controllers

Do not build a new deployment on ingress-nginx. Upstream has wound the project down, so it is not somewhere to put a platform you intend to run.The chart emits plain Ingress objects, so it will render against ingress-nginx and largely work — but we do not test that path, and we will not fix issues specific to it. If you are already on ingress-nginx, plan a move to Traefik; the only thing that changes in this chart is className and the annotation block.

The three hostnames

All three derive from global.domain unless you override them individually.
auth.<domain> must be reachable from outside the cluster. It is tempting to keep Keycloak internal, but browsers get redirected there during login and agents fetch tokens from it. When ingress is on, the chart switches Keycloak’s issuer to the public URL — tokens minted with an internal issuer would be rejected by anything validating them from outside.

The base configuration

Two things to know before the examples:
  • tls.secretName is a single value shared by all three Ingresses. One certificate has to cover app., api. and auth. — a SAN or wildcard cert. If you need a certificate per host, set tls.enabled: false and drive TLS from your controller’s annotations instead (that’s what the AWS example below does).
  • Annotations merge, with per-component winning over global. So you can set a shared block globally and add one annotation to just the gateway.

Worked examples

The chart emits standard Ingress objects, so moving is a values change rather than a redeployment:
  1. Install Traefik and confirm its IngressClass exists — kubectl get ingressclass.
  2. Swap global.ingress.className from nginx to traefik.
  3. Replace the nginx.ingress.kubernetes.io/* annotations with the Traefik equivalents above. The one that matters is the read timeout — it moves from a per-Ingress annotation to Traefik’s static config.
  4. helm upgrade, then re-point DNS at the Traefik load balancer.
Run both controllers side by side during the cutover if you can: the two IngressClasses are independent, so nothing conflicts.

DNS

The chart creates Ingress objects; it does not touch DNS. Point all three names at your ingress controller’s address:
A wildcard *.swarmd.example.com covers all three and anything you add later.
Testing on minikube without DNS? Use nip.io, which resolves any <anything>.<ip>.nip.io to that IP:

Verifying

Then check each hop:
That last one is the check worth doing. It must print https://auth.swarmd.example.com/realms/swarmd. If it prints an in-cluster service URL, ingress was enabled without Keycloak picking up the public hostname, and every externally-issued token will fail audience validation.
The controller hasn’t claimed it — usually a className that matches no IngressClass in the cluster:
The controller is answering but has no rule for that host. Check the Host header matches exactly — api.<domain>, not the bare domain — and that DNS points where you think.
Keycloak is advertising the wrong issuer. Confirm global.ingress.enabled is true (not just annotations set), and re-check the discovery document above.
Proxy timeout, not Swarmd. Raise it — respondingTimeouts.readTimeout on Traefik, idle_timeout.timeout_seconds on ALB. The relay holds a conversation send for up to 100 s before returning 202.

Next

Configuration

SMTP, secrets, app settings and optional components.

Presets

Ready-made values files, including HTTPS shapes.