Skip to main content
Deploy the PraisonAI gateway (WebSocket + REST on port 8765) to Kubernetes with the official Helm chart.

Quick Start

1

Create the auth token Secret

Pre-create the Secret out-of-band (GitOps-friendly) instead of putting a token in Git.
2

Install the chart from a local checkout

Point the release at the pre-created Secret. The same chart is also installable via praisonai deploy helm --chart gateway (see the Helm CLI Wrapper).
3

Verify with a port-forward

Forward the Service and hit the health endpoint.
Scaling replicas > 1 requires a distributed turn lock — the default in-process lock does not serialise turns across pods, so two pods will run concurrent turns on one session and corrupt the shared transcript. Set gateway.turn_lock.backend: redis (see Gateway Turn Lock) before increasing replicaCount.

How It Works

Helm renders the templates into Kubernetes objects, then the gateway container starts and reads its auth token from the Secret.

Configuration Options

Every key below is from src/praisonai-bot/infra/helm/praisonai-gateway/values.yaml. Default ingress.annotations:

Security — Auth Is Fail-Fast by Default

When auth.enabled=true (the default), the chart refuses to render unless a token source is provided.
With auth.enabled=true you must set auth.existingSecret or auth.token. Without one, the pod would reference a Secret that is never created and fail with CreateContainerConfigError, so the chart fails fast at render time instead.
Without a token source, the render fails:
  • auth.enabled=true only (no ingress):
    auth.enabled is true but no auth.existingSecret or auth.token was provided. Set one of them, or disable auth with auth.enabled=false.
  • auth.enabled=true and ingress.enabled=true:
    auth.enabled and ingress.enabled are true but no auth.existingSecret or auth.token was provided. Refusing to expose the gateway without a GATEWAY_AUTH_TOKEN.
To run without a token (e.g. local testing behind trusted networking) set auth.enabled=false.
Never combine auth.enabled=false with ingress.enabled=true — that exposes an unauthenticated gateway to the network.
The injected env var is always named GATEWAY_AUTH_TOKEN — that is the only name the gateway reads. auth.secretKey selects which data key in the Secret to read, not the env var name. Renaming auth.secretKey does not rename the env var.

Passing Other Secrets (LLM Keys) via env

Pass provider keys with the valueFrom.secretKeyRef pattern.

WebSocket Ingress — Sticky Sessions

The gateway is stateful per WebSocket connection, so multi-replica setups need sticky sessions.
Before scaling replicaCount > 1 (or enabling autoscaling), enable sticky sessions or a shared session backend. Otherwise reconnecting clients may land on a different pod and lose state.
The default NGINX annotations set long read/send timeouts. Add a cookie affinity annotation for sticky sessions:

Ingress + TLS Example

Expose the gateway on a real hostname with TLS.

Autoscaling (HPA)

Enable CPU-based scaling with an HPA.
Multi-replica gateways hold per-connection WebSocket state. Configure sticky sessions (see WebSocket Ingress) before enabling autoscaling.

Scope

This chart intentionally covers the gateway only. Other services (serve, claw, bots) run from the same GHCR image and can be templated similarly if needed, but are out of scope for this chart.

Best Practices

Inline tokens end up in Git. Pre-created Secrets don’t — create the Secret out-of-band and reference it with auth.existingSecret.
The default image.tag falls back to Chart appVersion ("latest"), which drifts. Pin a released tag such as "4.6.157" for reproducible deployments.
WebSocket state is per-pod. Scale beyond one replica only after enabling sticky sessions or a shared session backend.
The chart ships resources: {} by default, so the pod has no guaranteed CPU/memory. Set requests and limits — commented-out example values are in values.yaml.

Gateway & Control Plane

The service this chart deploys.

Docker Deployment

Docker deployment alternative.