Key points
- The chart deploys PostgreSQL, API, AAA, dispatcher, git-bot, UI, Gotenberg, and the Kubernetes runner.
- Install the CLI from the latest GitHub Release assets before running
nopsai install kubernetes; remove the downloaded archive after extraction. nopsai install kubernetesgenerates non-secret values,installation.md, and a separate Secret manifest.- The runner Deployment and agent pods use an RBAC-bearing runner ServiceAccount; step pods use a separate no-RBAC workload ServiceAccount.
topology.dispatcherGRPCAddressdefaults todispatcher:9090and is injected into API and runner pods.- Cross-namespace runners normally need
dispatcher.<platform-namespace>.svc.cluster.local:9090. - Private registries work through explicit
imagePullSecrets. - The chart version is the only version to change: NopsAI image tags resolve from
global.releaseVersion, and an empty value falls back to the chartappVersion. Per-imagetaganddigestvalues stay available as intentional overrides.
Before you start
- Cluster access
- A namespace you can install into
kubectl auth can-i create deployment -n nopsai - Helm
- Helm 3
helm version --short - Secrets
- The platform secrets available as Kubernetes secrets rather than a local
.env - Registry access
- Pull access to the platform images from the cluster, with
imagePullSecretswhere the registry is private
Steps
- 01
Render before you apply
Plan mode renders the manifests without touching the cluster, which is the cheapest way to catch a bad value file.
Render the chartbash helm template nopsai deploy/helm/nopsai --values my-values.yamlExpected result- Rendered manifests for the API, AAA, dispatcher, git-bot, UI, and supporting services.
- 02
Install or upgrade
The same command does both, which keeps the first install and every later one on one path.
Install the releasebash helm upgrade --install nopsai deploy/helm/nopsai \ --namespace nopsai --create-namespace \ --values my-values.yaml --waitVerify- kubectl get pods -n nopsai
- 03
Confirm the dispatcher is reachable by runners
Runners dial out, so the dispatcher address in the values must be resolvable from wherever the runners live — cross-namespace runners need the fully qualified service name.
Check the servicebash kubectl get svc dispatcher -n nopsaiExpected result- The dispatcher answers on port 9090, which is the port
DISPATCHER_GRPC_ADDRESSmust point at.
- The dispatcher answers on port 9090, which is the port
- 04
Install a Kubernetes runner
Generate the runner install from the dispatcher workspace rather than hand-writing a manifest, so identity, scopes, and TLS material come from the control plane.
Verify- The runner registers and appears in the fleet view with its scopes.
How it works
Keeping step pods on a no-RBAC service account is what stops workload code from calling the Kubernetes API. Do not merge the two accounts to simplify a chart values file.
Managed PostgreSQL is supported by disabling the bundled StatefulSet and replacing the generated database URL.
The Kubernetes runner gives each run an agent-owned PVC-backed workspace rather than an emptyDir, so the workspace survives step pod churn within the run.
System Logs on Kubernetes use read-only pods and pods/log RBAC instead of the Docker socket proxy.
Field reference
RUNTIME_POOLSkubernetes runnermapOptionalNone
Named Kubernetes runtime pools selectable through pipeline or step runtime_pool.
RUNTIME_POOLS=gpu:node-role=gpuconfig/config.go
KUBERNETES_NAMESPACEkubernetes runnerstringOptionalRunner namespace
Namespace where the runner creates agent pods, step pods, and workspace PVCs.
KUBERNETES_NAMESPACE=nopsai-runnersconfig/config.go
KUBERNETES_SERVICE_ACCOUNTkubernetes runnerstringOptionalChart-managed runner service account
RBAC-bearing service account used by the runner Deployment and agent pods.
KUBERNETES_SERVICE_ACCOUNT=nopsai-runnerdeploy/helm/nopsai
KUBERNETES_WORKLOAD_SERVICE_ACCOUNTkubernetes runnerstringOptionalChart-managed no-RBAC service account
Separate service account for step pods, deliberately without cluster permissions.
KUBERNETES_WORKLOAD_SERVICE_ACCOUNT=nopsai-workloadKeeping step pods on a no-RBAC account is what stops workload code from calling the Kubernetes API.
deploy/helm/nopsai
KUBERNETES_IMAGE_PULL_SECRETSkubernetes runnerstring[]OptionalNone
Infrastructure-owned pull secrets attached to runner and step pods for private registries.
KUBERNETES_IMAGE_PULL_SECRETS=regcredconfig/config.go
KUBERNETES_STORAGE_CLASSkubernetes runnerstringOptionalCluster default
Storage class used for the agent-owned workspace PVC.
KUBERNETES_STORAGE_CLASS=fast-ssdKUBERNETES_DEFAULT_WORKSPACE_SIZEkubernetes runnerstringOptionalChart default
Requested size of the run workspace PVC.
KUBERNETES_DEFAULT_WORKSPACE_SIZE=20GiKUBERNETES_AFFINITY_ENABLEDkubernetes runnerbooleanOptionalChart default
Whether step pods in a run are scheduled onto the same node by default.
KUBERNETES_AFFINITY_ENABLED=truepipeline affinity_enabled
KUBERNETES_CLEANUP_FINISHED_PODSkubernetes runnerbooleanOptionalChart default
Whether finished step pods are deleted after their status is reported.
KUBERNETES_CLEANUP_FINISHED_PODS=trueExamples
nopsai install kubernetes --version 1.4.2Limits
- The repository documents no HPA/autoscaling implementation and no Kubernetes NetworkPolicy set.
- Helm does not manage PostgreSQL beyond the bundled StatefulSet.
Implementation evidence
deploy/helm/nopsai/values.yamlChart values including topology and service accounts.
doc/kubernetes-runner.mdRunner runtime, PVC workspace behavior, affinity, and manifests.

