Skip to main content
The KaireonAI Helm chart deploys the complete platform to any Kubernetes cluster — EKS, GKE, AKS, or self-managed. The chart includes the API server, worker, PostgreSQL, Redis, PgBouncer, Prometheus, Grafana, ingress, network policies, and RBAC resources.

Overview

The chart packages everything needed for a production KaireonAI deployment:

Prerequisites

  • Kubernetes 1.24+
  • Helm 3.x
  • kubectl configured for your cluster
  • Container images pushed to a registry accessible from the cluster

Quick Start

1

Add the chart

Clone the KaireonAI repository which includes the Helm chart in helm/:
2

Install with minimal values

For a quick test deployment with everything in-cluster:
3

Verify the deployment

Or use the deploy script which handles namespace creation and secret generation:

Deployment Modes

KaireonAI supports three deployment modes depending on your environment and requirements.
Everything runs inside the cluster with minimal resources. Uses the internal PostgreSQL and Redis StatefulSets. No external dependencies required.Best for: Local development, CI testing, quick demos.
Resource footprint: Fits on a single t3.medium node (~2 vCPU, 4 GiB).Key overrides in values-minimal.yaml:
  • API and worker: 1 replica each
  • HPA and KEDA disabled
  • Prometheus and Grafana disabled
  • Reduced resource requests (256Mi memory, 250m CPU)
  • Smaller PVC sizes (5 GiB database, 2 GiB Redis)
Connect to managed services (RDS, ElastiCache, Cloud SQL, etc.) while running the application tier in Kubernetes. This is the recommended mode for production.Best for: Staging and production environments.
Requires a config file specifying external database and Redis endpoints. See the Example Configurations section below.
Deploys everything including Prometheus and Grafana with 6 auto-provisioned dashboards. Can use either internal or external database and Redis.Best for: Production environments where you want the full observability stack deployed alongside the application.
The default values.yaml enables the full mode with 3 API replicas, 2 worker replicas, HPA, KEDA autoscaling, Prometheus, and Grafana.

Values Reference

All configurable values are defined in helm/values.yaml. The sections below document each configuration group.

Global

API

The HPA includes scale-up/down behavior policies:
  • Scale up: stabilization window of 60s, add up to 4 pods per 60s
  • Scale down: stabilization window of 300s, remove up to 10% of pods per 60s

Worker

ML Worker

When enabled, the chart automatically injects ML_WORKER_URL into the API pods.

Config

config.CORS_ALLOWED_ORIGINS ships empty on purpose. With NODE_ENV=production (the default) the API’s startup env-validation refuses to boot unless it is set to an explicit, non-wildcard origin, so the chart fails at helm install / helm template time with an actionable message rather than letting the pod crash-loop. Supply your app’s public origin(s) at install:
For multiple origins, escape the commas so Helm treats them as one string value: --set config.CORS_ALLOWED_ORIGINS=https://app.example.com\,https://admin.example.com (or set it in a -f values override, where commas need no escaping). scripts/deploy.sh reads a CORS_ALLOWED_ORIGINS env var and defaults to http://localhost:3000 for its dev-mode path.

Database

Set database.mode to control how PostgreSQL is provisioned:
  • internal — Deploys a PostgreSQL 16 StatefulSet inside the cluster
  • external — Connects to a managed database (RDS, Cloud SQL, Supabase, etc.)
Internal mode values:External mode values:

Secrets

With secrets.provider: kubernetes the chart templates the kaireon-secrets Secret with the keys above plus the derived DATABASE_URL / REDIS_URL (and GF_ADMIN_PASSWORD when Grafana is enabled). Set secrets.provider: aws-secrets-manager to pull the same keys from an ExternalSecret instead.
WEBHOOK_SIGNING_SECRET and API_KEY_PEPPER are both required when NODE_ENV=production — the API refuses to start without them. The chart now templates both keys (in secrets.yaml for the kubernetes provider and external-secret.yaml for aws-secrets-manager), and scripts/deploy.sh auto-generates them alongside the other secrets. Provide your own values via --set secrets.WEBHOOK_SIGNING_SECRET=… / --set secrets.API_KEY_PEPPER=…, a values override, or your external secrets manager.
Generate secrets with openssl rand -base64 32. Never commit plaintext secrets to version control. Use --set flags, sealed secrets, or an external secrets manager in production.

Redis

Set redis.mode to control how Redis is provisioned:
  • internal — Deploys a Redis 7 StatefulSet inside the cluster
  • external — Connects to a managed Redis (ElastiCache, Upstash, etc.)
Internal mode values:External mode values:

PgBouncer

Defined in helm/values.yaml:209-225. PgBouncer fronts PostgreSQL so the API tier shares a small pool against the database while individual Next.js request handlers can each open their own client connection.
Transaction pooling (transaction mode) is recommended for Next.js applications. It allows multiple clients to share database connections between transactions, significantly reducing the number of connections to PostgreSQL.

Ingress

AWS ALB Ingress (when className: alb):Nginx Ingress (when className: nginx):

DNS

Defined in helm/values.yaml:246-249. When enabled, the chart adds the annotations external-dns expects on the Ingress so Route53 records track the cluster automatically. The companion external-dns controller is not installed by this chart — operators run it once per cluster from the upstream Helm chart.

Monitoring

Set the Grafana admin password via --set or a sealed secret in production. Never leave it empty in a publicly accessible deployment.

Event Bus (Optional)

Set config.EVENT_PUBLISHER to activate an event bus backend. The default is redis which requires no extra configuration.
Kafka:Amazon MSK:Amazon EventBridge:Amazon Kinesis:

Interaction Store (Optional)

Set config.INTERACTION_STORE to activate an alternative interaction history backend. The default is pg (PostgreSQL).
DynamoDB:Amazon Keyspaces:ScyllaDB:

Search Index (Optional)

Set config.SEARCH_INDEX to activate an alternative search backend. The default is pg (PostgreSQL tsvector).

Cron Tier

When cron.enabled: true (the default) the chart creates one Kubernetes CronJob per entry in cron.schedules. Each job runs a small curlimages/curl container that fires a single authenticated POSTcurl -H "Authorization: Bearer $CRON_SECRET" <baseUrl><path> — at the in-cluster API service; the actual work runs inside the API tier.Seven schedules ship enabled by default:
This tier is for multi-replica deployments. On a single replica the API container already runs an in-process maintenance scheduler and flow scheduler that fire these jobs on their own once CRON_SECRET (or CRON_TOKEN) is set — set cron.enabled: false to rely on those instead, or disable the in-process schedulers (MAINTENANCE_SCHEDULER_ENABLED=false, FLOW_INTERNAL_SCHEDULER_ENABLED=false) when you prefer the CronJobs. The API tier must have CRON_SECRET available for the jobs to authenticate.

Outbox Publisher

When outboxPublisher.enabled: true (the default) the chart deploys a dedicated pod that polls the outbox_events table and publishes each event through the configured EVENT_PUBLISHER. Splitting it from the main worker tier keeps outbox tail-latency independent of long-running batch jobs.

Large-Topology Aliases

The following keys appear only in the large-enterprise overlay at helm/values-large.yaml. The base chart (helm/values.yaml) does not define them — they are layered in via helm upgrade -f helm/values.yaml -f helm/values-large.yaml. Each is a high-level alias that the chart maps onto the per-backend sections above. See values-large.yaml — enterprise topology for the full overlay.
Defined in helm/values-large.yaml:163. A single integer that records how many read replicas the operator has provisioned alongside the primary. Advisory only — the chart does not itself create RDS replicas; consumers (e.g. the read-only analytics path) read this number when deciding whether to fan out reads.postgresExternalReplicas is meaningful only when database.mode: external (or, in the large overlay, postgres.mode: external). For internal-StatefulSet deployments leave it unset.
Defined in helm/values-large.yaml:173-175. A high-level alias that picks one of the per-backend blocks (kafka.*, msk.*, eventbridge.*, kinesis.*). The base chart instead drives this from config.EVENT_PUBLISHER (redis | kafka | msk | eventbridge | kinesis); the large overlay adds the alias for callers who prefer to read the choice as a single key. Either form is honoured — the operator should not set both unless the values agree.
Defined in helm/values-large.yaml:177-178. The large-overlay alias for config.INTERACTION_STORE. Selects which write path receives the partitioned interaction-history rows. Each backend still requires its own per-backend block (dynamodb.*, scylla.*, keyspaces.*) to be filled in.The chart does not provision the target store — the operator owns the DynamoDB table, Scylla cluster, or Keyspaces keyspace before flipping this value.

Grafana Dashboards

The chart includes 6 pre-built Grafana dashboards that are auto-provisioned from helm/dashboards/. When monitoring.grafana.enabled=true, these dashboards are available immediately after deployment.
KaireonAI exposes Prometheus metrics at /api/metrics (the bundled Prometheus deployment is pre-configured to scrape this path on port 3000; the endpoint requires an admin role or a valid API key). Key metrics include kaireon_decision_latency_ms, kaireon_decision_delivery_total, kaireon_pipeline_execution_latency_ms, kaireon_http_request_duration_seconds, and kaireon_dlq_depth.

Example Configurations

Dev / Testing (Minimal)

Uses internal PostgreSQL and Redis with minimal resources. No external dependencies needed.
values-minimal.yaml

EKS with RDS + ElastiCache

Production deployment on AWS with managed database and cache services.

GKE / Self-Managed with Nginx Ingress

Use nginx ingress controller with cert-manager for automatic TLS certificates.
values-gke.yaml

With Kafka and DynamoDB

Production deployment using Kafka for event streaming and DynamoDB for interaction history.
values-enterprise.yaml

Upgrading

To upgrade an existing deployment to a new version:
Database migrations run automatically on API pod startup via Prisma. Before upgrading, verify the migration is backward-compatible. If a migration requires downtime, scale down the API deployment first.
To roll back a failed upgrade:

Next Steps

Kubernetes Deployment

Architecture overview, troubleshooting, and database options.

ML Worker

Configure the ML Worker for AI-powered analysis features.

Infrastructure Backends

Configure Kafka, DynamoDB, OpenSearch, and other backends.

Cloud Deployment

One-click deployment to AWS App Runner.