Chart overrides and tuning
Configure logging, worker concurrency, API environment variables, restricted security contexts, pod disruption budgets, and extra manifests for self-hosted Dreadnode.
Everything on this page is chart configuration, applied by a redeploy. Helm operators set values in an overlay. Embedded Cluster operators use dedicated Admin Console fields or their matching KOTS ConfigValues items. Advanced Helm Values is the escape hatch for everything without a dedicated Embedded Cluster field.
Use the full Helm values surface
Section titled “Use the full Helm values surface”The same umbrella-chart values document works on all three configuration paths:
Put the values in your Helm overlay:
dreadnode-api: config: workers: concurrency: evaluation: 2Open Config → Advanced Helm Values → Helm Values and paste the umbrella-chart document:
dreadnode-api: config: workers: concurrency: evaluation: 2Select Save config, run the preflight checks, then select Deploy. The installer merges this document after the dedicated fields, so an advanced value wins when both interfaces set the same chart key.
Put the same document in the advanced_helm_values item:
apiVersion: kots.io/v1beta1kind: ConfigValuesspec: values: advanced_helm_values: value: | dreadnode-api: config: workers: concurrency: evaluation: 2The values persist across configuration changes and upgrades. Paste the values document without a
leading --- separator; Embedded Cluster indents it into a larger document during deployment.
Chart schemas validate the settings they cover. For example, a misspelled
dreadnode-api.config.loging key is rejected, and an unsupported logging level is rejected with
the allowed values. Not every subchart has a complete schema, so preflight success does not prove
every advanced key is valid. Verify the rendered workload after changing an advanced setting.
Open the shell for Kubernetes resources
Section titled “Open the shell for Kubernetes resources”SSH to an Embedded Cluster controller node, then start the shell shipped with the installer:
sudo ./dreadnode shellThe shell puts kubectl and helm on PATH and configures access to the cluster. Dreadnode runs
in the kotsadm namespace. Use it for Kubernetes resources such as Secrets that the values document
references, not for chart-value overrides. Run commands inside this shell without sudo, then type
exit when you finish.
Logging
Section titled “Logging”dreadnode-api: config: logging: level: info structured: falseOpen Config → Logging. Set Log Level and Emit structured JSON logs. The UI offers
debug, info, warning, and error.
apiVersion: kots.io/v1beta1kind: ConfigValuesspec: values: log_level: value: "info" log_structured: value: "0"Supported levels are trace, debug, info, success, warning, error,
and critical. Use debug while investigating an incident. trace is much
more verbose and is intended for framework-level diagnosis.
The Admin Console offers the four common levels. To use trace, success, or critical on
Embedded Cluster, set dreadnode-api.config.logging.level through
Advanced Helm Values.
Worker concurrency
Section titled “Worker concurrency”Each API pod runs workers for evaluations, Worlds jobs, training, and optimization. The default concurrency is one worker of each type per API pod.
dreadnode-api: replicaCount: 2 config: workers: concurrency: evaluation: 2 worlds: 2 training: 1 optimization: 1Open Config → Scaling & Resources, enable Set API replicas and worker concurrency, then set API Replicas and each Concurrent … per Pod field.
apiVersion: kots.io/v1beta1kind: ConfigValuesspec: values: scaling_customize: value: "1" api_replicas: value: "2" worker_concurrency_evaluation: value: "2" worker_concurrency_worlds: value: "2" worker_concurrency_training: value: "1" worker_concurrency_optimization: value: "1"Increase a value when its queue is backing up and the API pod has available CPU and memory. Every API replica runs its own set of workers, so adding replicas raises total concurrency as well. The resource preset controls how much CPU and memory each pod gets; these settings control how much of it runs in parallel. Check the pods have headroom against the preset before raising either.
Additional environment variables
Section titled “Additional environment variables”Use extraEnv or extraEnvFrom only for API settings that do not have a
first-class chart value:
dreadnode-api: extraEnv: - name: SOME_FEATURE_FLAG value: 'true' extraEnvFrom: - secretRef: name: my-extra-secretsOpen Config → Advanced Helm Values → Helm Values and paste the Helm block shown in the preceding tab.
apiVersion: kots.io/v1beta1kind: ConfigValuesspec: values: advanced_helm_values: value: | dreadnode-api: extraEnv: - name: SOME_FEATURE_FLAG value: "true" extraEnvFrom: - secretRef: name: my-extra-secretsPrefer extraEnvFrom for credentials so they remain in Kubernetes Secrets.
For Embedded Cluster, create the referenced Secret from the
cluster shell:
kubectl -n kotsadm create secret generic my-extra-secrets \ --from-literal=SOME_API_TOKEN='<api-token>' \ --dry-run=client -o yaml | kubectl apply -f -Deploy the configuration, then inspect the effective Deployment if you need to verify the rendered environment:
kubectl -n kotsadm get deployment dreadnode-api -o yamlFor supported chart settings and defaults, pull the chart’s values file — API
settings live under the dreadnode-api key:
helm show values oci://registry.replicated.com/dreadnode/dreadnode --version <version>Restrict container security contexts
Section titled “Restrict container security contexts”Clusters with a restrictive admission policy (Pod Security Admission restricted, Kyverno, Gatekeeper) often reject containers that don’t declare allowPrivilegeEscalation: false, a capability drop and a seccomp profile. Dreadnode’s own service containers already disallow privilege escalation and drop all capabilities. The rest is off by default, so upgrades leave running workloads unchanged: the bundled data stores, the API’s wait-for init containers, the sandbox pod’s init container and egress sidecar, and a seccomp profile on the API, frontend and docs pods. Turn them on together:
dreadnode-base: postgresql: containerSecurityContext: &restricted allowPrivilegeEscalation: false capabilities: drop: [ALL] seccompProfile: type: RuntimeDefault clickhouse: initContainerSecurityContext: *restricted containerSecurityContext: *restricted minio: containerSecurityContext: *restricteddreadnode-api: podSecurityContext: seccompProfile: type: RuntimeDefault initContainers: waitFor: securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL]dreadnode-frontend: podSecurityContext: seccompProfile: type: RuntimeDefaultdreadnode-docs: podSecurityContext: seccompProfile: type: RuntimeDefaultdreadnode-sandbox-server: execdInstallerSecurityContext: *restricted egress: securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL]Open Config → Pod Security & Disruption Budgets, select Restrict container security contexts, save the configuration, and deploy.
apiVersion: kots.io/v1beta1kind: ConfigValuesspec: values: restricted_security_contexts: value: '1'minio.containerSecurityContext also covers the Job that creates the MinIO buckets, and the ClickHouse init container keeps its runAsUser: 101. The sandbox egress sidecar still runs as root with NET_ADMIN, which it needs to install its packet filter, so a policy that forbids either needs an exception scoped to the egress container. The agent’s own sandbox container isn’t changed, because restricting it blocks sudo; see Tighten sandbox pod security contexts.
Each containerSecurityContext replaces the container’s securityContext as a whole, so you can add fields such as readOnlyRootFilesystem per data store. Check each workload after you add one, since the data stores write outside their volumes.
Create pod disruption budgets
Section titled “Create pod disruption budgets”dreadnode-api: podDisruptionBudget: enabled: truedreadnode-base: postgresql: podDisruptionBudget: enabled: trueOpen Config → Pod Security & Disruption Budgets, select Create PodDisruptionBudgets, save the configuration, and deploy. This creates a budget for every workload.
apiVersion: kots.io/v1beta1kind: ConfigValuesspec: values: pod_disruption_budgets: value: '1'On the Helm path each workload has its own podDisruptionBudget block, all off by default: dreadnode-api, dreadnode-frontend, dreadnode-docs, dreadnode-litellm, dreadnode-sandbox-controller, dreadnode-sandbox-server and dreadnode-sandbox-server.gateway, plus postgresql, clickhouse and minio under dreadnode-base. A budget defaults to maxUnavailable: 1, so a single-replica workload can still be drained from its node. Set minAvailable instead (an integer or a percentage) to hold pods up during a drain; it takes precedence over maxUnavailable.
Add extra manifests
Section titled “Add extra manifests”Use extraObjects for resources your cluster policy requires that the chart doesn’t ship, such as a LimitRange or a NetworkPolicy. Helm renders each entry with the release, through tpl, so it can reference .Release and .Values:
extraObjects: - apiVersion: v1 kind: LimitRange metadata: name: '{{ .Release.Name }}-container-defaults' spec: limits: - type: Container default: cpu: 500m memory: 512Mi