Skip to content

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:

  1. Prepare Kubernetes cluster (namespaces, storage)
  2. Configure registry access (Kindo private registry)
  3. Deploy peripheries (third-party services)
  4. Configure secrets
  5. Deploy Kindo applications
  6. Configure DNS and ingress
  7. 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

Terminal window
# Periphery services (third-party)
kubectl create namespace unleash
kubectl create namespace presidio
kubectl create namespace speaches
kubectl create namespace external-secrets # optional
# Kindo application services
kubectl create namespace api
kubectl create namespace next
kubectl create namespace litellm
kubectl create namespace llama-indexer
# Kindo worker services
kubectl create namespace external-poller
kubectl create namespace external-sync
kubectl create namespace credits
kubectl create namespace audit-log-exporter
kubectl create namespace task-worker-ts
# Kindo supporting services
kubectl create namespace ssoready
kubectl create namespace cerbos
# Label all namespaces
for 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=kindo
done

Configure Storage Class

Verify a default storage class exists:

Terminal window
kubectl get storageclasses

If 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:

Terminal window
REGISTRY_USERNAME="your-username" # Provided by Kindo
REGISTRY_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=$namespace
done

Test access:

Terminal window
helm pull oci://registry.kindo.ai/kindo-helm/api \
--version 2025.08.2 \
--username "$REGISTRY_USERNAME" \
--password "$REGISTRY_PASSWORD"
rm -f api-*.tgz

Step 3: Deploy Peripheries

Peripheries are open-source and third-party services that Kindo depends on. Install them from their public Helm repositories.

Terminal window
helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets \
external-secrets/external-secrets \
--namespace external-secrets \
--create-namespace \
--set installCRDs=true

Unleash (required)

Feature flag management platform:

Terminal window
helm repo add unleash https://docs.getunleash.io/helm-charts
helm install unleash unleash/unleash \
--namespace unleash \
-f unleash-values.yaml

Configure 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:

Terminal window
helm repo add qdrant https://qdrant.github.io/qdrant-helm
helm install qdrant qdrant/qdrant \
--namespace qdrant \
--create-namespace \
--set replicaCount=3 \
--set persistence.size=100Gi

Step 4: Configure Secrets

Create Kubernetes secrets for each service. Use External Secrets Operator (recommended) or create secrets manually.

Generate Required Secrets

Terminal window
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:

Terminal window
# Deploy API
helm install api oci://registry.kindo.ai/kindo-helm/api \
--namespace api \
-f api-values.yaml \
--username "$REGISTRY_USERNAME" \
--password "$REGISTRY_PASSWORD"
# Deploy Next.js frontend
helm install next oci://registry.kindo.ai/kindo-helm/next \
--namespace next \
-f next-values.yaml \
--username "$REGISTRY_USERNAME" \
--password "$REGISTRY_PASSWORD"
# Deploy LiteLLM
helm 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

Terminal window
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 $ns
done

Step 6: Configure DNS and Ingress

Create DNS records pointing to your ingress controller:

SubdomainService
app.kindo.company.comNext.js frontend
api.kindo.company.comAPI service
sso.kindo.company.comSSOReady
litellm.kindo.company.comLiteLLM proxy
unleash.kindo.company.comUnleash dashboard

Configure ingress resources for each service with TLS certificates.

Step 7: Post-Deployment Configuration

  1. Configure Unleash feature flags — Set up model mappings and feature variants (see Model Configuration).

  2. Set up SSO — Configure SSOReady for authentication (see SSO Setup).

  3. Add AI models — Register at least one AI model (see Model Configuration).

  4. Configure integrations — Set up Nango and MCP servers (see Integrations).

  5. Create initial organization and user — Run the setup SQL to create the first admin user.

  6. Test end-to-end — Log in, run a chat query, and verify agent functionality.

Verification

After deployment, verify:

Terminal window
# Check all pods are running
kubectl get pods -A -l app.kubernetes.io/part-of=kindo
# Check ingress endpoints
kubectl get ingress -A
# Test API health
curl https://api.kindo.company.com/health
# Test frontend
curl -I https://app.kindo.company.com

Troubleshooting

Pods not starting

Terminal window
# Check pod events
kubectl describe pod <pod-name> -n <namespace>
# Check logs
kubectl logs <pod-name> -n <namespace>

Database connection issues

Verify PostgreSQL is accessible from within the cluster:

Terminal window
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:

Terminal window
kubectl get secret kindo-registry -n <namespace>