Installation Guide (Cloud Agnostic)
This runbook provides step-by-step instructions for deploying Kindo on your self-managed Kubernetes cluster using Helm charts.
Overview
Deployment method: Helm charts Target: Any Kubernetes cluster (on-premises, AWS, GCP, Azure, etc.) Estimated time: 2—3 hours
Deployment order:
- Prepare Kubernetes cluster (namespaces, storage)
- Configure registry access (Kindo private registry)
- Deploy peripheries (third-party services)
- Configure secrets
- Deploy Kindo applications
- Configure DNS and ingress
- Post-deployment configuration
Terminology:
- Peripheries — Third-party/open-source services (Unleash, External Secrets, Qdrant)
- Kindo Applications — Services packaged by Kindo (API, Next.js, LiteLLM, workers)
Prerequisites
Before starting, verify all requirements from the Infrastructure Requirements guide:
- Kubernetes cluster v1.32+ with 3+ nodes
- PostgreSQL, Redis, and RabbitMQ provisioned
- S3-compatible storage configured
- Ingress controller and cert-manager installed
- All credentials collected
Step 1: Prepare Kubernetes Cluster
Create Namespaces
# Periphery services (third-party)kubectl create namespace unleashkubectl create namespace presidiokubectl create namespace speacheskubectl create namespace external-secrets # optional
# Kindo application serviceskubectl create namespace apikubectl create namespace nextkubectl create namespace litellmkubectl create namespace llama-indexer
# Kindo worker serviceskubectl create namespace external-pollerkubectl create namespace external-synckubectl create namespace creditskubectl create namespace audit-log-exporterkubectl create namespace task-worker-ts
# Kindo supporting serviceskubectl create namespace ssoreadykubectl create namespace cerbos
# Label all namespacesfor ns in api next litellm llama-indexer external-poller external-sync \ credits audit-log-exporter task-worker-ts ssoready cerbos unleash \ presidio speaches; do kubectl label namespace $ns app.kubernetes.io/managed-by=kindo kubectl label namespace $ns app.kubernetes.io/part-of=kindodoneConfigure Storage Class
Verify a default storage class exists:
kubectl get storageclassesIf no default exists, create one appropriate for your environment.
Step 2: Configure Registry Access
Kindo Helm charts are stored in a private OCI registry. Create secrets to access them:
REGISTRY_USERNAME="your-username" # Provided by KindoREGISTRY_PASSWORD="your-password" # Provided by Kindo
for namespace in api next litellm llama-indexer external-poller external-sync \ credits audit-log-exporter task-worker-ts ssoready cerbos; do kubectl create secret docker-registry kindo-registry \ --docker-server=registry.kindo.ai \ --docker-username="$REGISTRY_USERNAME" \ --docker-password="$REGISTRY_PASSWORD" \ --namespace=$namespacedoneTest access:
helm pull oci://registry.kindo.ai/kindo-helm/api \ --version 2025.08.2 \ --username "$REGISTRY_USERNAME" \ --password "$REGISTRY_PASSWORD"rm -f api-*.tgzStep 3: Deploy Peripheries
Peripheries are open-source and third-party services that Kindo depends on. Install them from their public Helm repositories.
External Secrets Operator (recommended)
helm repo add external-secrets https://charts.external-secrets.iohelm install external-secrets \ external-secrets/external-secrets \ --namespace external-secrets \ --create-namespace \ --set installCRDs=trueUnleash (required)
Feature flag management platform:
helm repo add unleash https://docs.getunleash.io/helm-chartshelm install unleash unleash/unleash \ --namespace unleash \ -f unleash-values.yamlConfigure unleash-values.yaml with your PostgreSQL connection details and ingress settings.
Unleash Edge (required)
Feature flag edge proxy, deployed after Unleash is running.
Presidio (required)
PII detection and anonymization service.
Speaches (required)
Text-to-speech service.
Qdrant (optional)
Vector database, required if not using Pinecone:
helm repo add qdrant https://qdrant.github.io/qdrant-helmhelm install qdrant qdrant/qdrant \ --namespace qdrant \ --create-namespace \ --set replicaCount=3 \ --set persistence.size=100GiStep 4: Configure Secrets
Create Kubernetes secrets for each service. Use External Secrets Operator (recommended) or create secrets manually.
Generate Required Secrets
NEXTAUTH_SECRET=$(openssl rand -base64 32)KEY_ENCRYPTION_KEY=$(openssl rand -base64 32)UM_INTERNAL_API_KEY=$(openssl rand -hex 32)LITELLM_MASTER_KEY=$(openssl rand -hex 32)UNLEASH_ADMIN_TOKEN=$(openssl rand -hex 32)UNLEASH_CLIENT_TOKEN=$(openssl rand -hex 32)Create Secrets per Namespace
Create Kubernetes secrets in each service namespace with the appropriate connection strings, API keys, and generated secrets.
Step 5: Deploy Kindo Applications
Deploy each Kindo application from the private registry:
# Deploy APIhelm install api oci://registry.kindo.ai/kindo-helm/api \ --namespace api \ -f api-values.yaml \ --username "$REGISTRY_USERNAME" \ --password "$REGISTRY_PASSWORD"
# Deploy Next.js frontendhelm install next oci://registry.kindo.ai/kindo-helm/next \ --namespace next \ -f next-values.yaml \ --username "$REGISTRY_USERNAME" \ --password "$REGISTRY_PASSWORD"
# Deploy LiteLLMhelm install litellm oci://registry.kindo.ai/kindo-helm/litellm \ --namespace litellm \ -f litellm-values.yaml \ --username "$REGISTRY_USERNAME" \ --password "$REGISTRY_PASSWORD"Continue deploying remaining services: llama-indexer, SSOReady, Cerbos, task-worker-ts, external-poller, external-sync, credits, and audit-log-exporter.
Verify Deployments
for ns in api next litellm llama-indexer ssoready cerbos task-worker-ts \ external-poller external-sync credits audit-log-exporter; do echo "=== $ns ===" kubectl get pods -n $nsdoneStep 6: Configure DNS and Ingress
Create DNS records pointing to your ingress controller:
| Subdomain | Service |
|---|---|
app.kindo.company.com | Next.js frontend |
api.kindo.company.com | API service |
sso.kindo.company.com | SSOReady |
litellm.kindo.company.com | LiteLLM proxy |
unleash.kindo.company.com | Unleash dashboard |
Configure ingress resources for each service with TLS certificates.
Step 7: Post-Deployment Configuration
-
Configure Unleash feature flags — Set up model mappings and feature variants (see Model Configuration).
-
Set up SSO — Configure SSOReady for authentication (see SSO Setup).
-
Add AI models — Register at least one AI model (see Model Configuration).
-
Configure integrations — Set up Nango and MCP servers (see Integrations).
-
Create initial organization and user — Run the setup SQL to create the first admin user.
-
Test end-to-end — Log in, run a chat query, and verify agent functionality.
Verification
After deployment, verify:
# Check all pods are runningkubectl get pods -A -l app.kubernetes.io/part-of=kindo
# Check ingress endpointskubectl get ingress -A
# Test API healthcurl https://api.kindo.company.com/health
# Test frontendcurl -I https://app.kindo.company.comTroubleshooting
Pods not starting
# Check pod eventskubectl describe pod <pod-name> -n <namespace>
# Check logskubectl logs <pod-name> -n <namespace>Database connection issues
Verify PostgreSQL is accessible from within the cluster:
kubectl run pg-test --rm -it --image=postgres:17 -- \ psql "postgresql://user:pass@host:5432/kindo"Registry pull errors
Verify the registry secret exists in the correct namespace:
kubectl get secret kindo-registry -n <namespace>