Helm installation
Install TestingOps on Kubernetes with the Helm chart
The chart lives in deploy/helm/cunda of the release package. It installs the application,
the migration job and (optionally) a MinIO object store. PostgreSQL is not installed by the
chart — provide a server with the pgvector extension (external database).
Requirements
- Kubernetes 1.27+ and Helm 3.
- A StorageClass that survives node loss (EBS, Ceph, NFS…). Local-path storage pins the pod to a dead node.
- An ingress controller (NGINX or Traefik) and a TLS secret for the host name.
- The same CPU/memory as a server install: requests 500m / 1 Gi, limits 2 CPU / 4 Gi.
1. Namespace and secrets
kubectl create namespace testingops
kubectl -n testingops create secret docker-registry testingops-registry \
--docker-server=<registry> --docker-username=<user> --docker-password=<password>
kubectl -n testingops create secret generic cunda-secrets \
--from-literal=DATABASE_URL='postgres://…' \
--from-literal=BETTER_AUTH_SECRET="$(openssl rand -hex 32)" \
--from-literal=CUNDA_MINIO_PASSWORD="$(openssl rand -hex 16)"
2. values.yaml
image:
repository: <registry>/testteam/cunda
tag: "2026.10.0"
imagePullSecrets: [{ name: testingops-registry }]
app:
publicUrl: https://testingops.company.com
env:
ANTHROPIC_API_KEY: "…" # or configure models from the UI later
TESTINGOPS_EXECUTION_PROVIDERS: runningops,manual
existingSecret: cunda-secrets
database:
migrateOnInstall: true
minio:
enabled: true
storage: 100Gi
persistence:
appData: { size: 50Gi, storageClassName: gp3 }
ingress:
enabled: true
className: nginx
host: testingops.company.com
tlsSecretName: testingops-tls
3. Install / upgrade
helm lint deploy/helm/cunda
helm upgrade --install testingops deploy/helm/cunda -n testingops -f values.yaml
kubectl -n testingops get pods -w # migrate job completes, then app becomes Ready
Upgrade to a new release: change image.tag, run the same helm upgrade --install. The chart
runs the migration job before the new application pod starts; replicas is fixed at 1 with
strategy: Recreate (the scheduler keeps in-process locks).
First login, license and configuration are the same as the Docker install (steps 5–6).
Notes from cluster validation
- The pod runs as uid 1000 and is compatible with the restricted PodSecurity profile;
fsGroup: 1000is required so the data volume is writable. - The startup probe allows up to 5 minutes for the first start (migrations + catalogue load).
/dev/shmis a 1 Gi memory-backed emptyDir; browser-based sessions need it.- Each node pulls the full image; plan disk as image size × nodes.