Configuration
All values are documented inline in the chart's values.yaml. Configuration is split across the following pages:
- Memory (QMD Hybrid Search) covers the hybrid search sidecar, update/embed CronJobs, resource tuning, and search weights.
- Network & egress filtering covers Gateway API routing, Ingress, NetworkPolicy, Chromium, Tailscale, and the Blocky DNS filter.
- LLM config (LiteLLM) covers the LiteLLM proxy, model routing, virtual keys, and caching.
- Observability covers the ClickHouse + HyperDX + OpenTelemetry stack.
This page covers the foundational settings: image, secrets, persistence, GitOps config, runtime, resources, pod, and service account.
For nested structures like config.desired, use a values file rather than --set.
Image
| Key | Default | Description |
|---|---|---|
image.repository | ghcr.io/openclaw/openclaw | Gateway container image |
image.tag | 2026.2.21 | Release tag validated for this chart version |
image.digest | sha256:ce2711... | Immutable digest to prevent tag drift |
image.pullPolicy | IfNotPresent | Always, IfNotPresent, or Never |
imagePullSecrets | [] | Pull secrets for private registries |
Each chart release pins both tag and digest to the validated candidate image.
Replica count
Fixed at 1. The Gateway holds exclusive listener state; multiple replicas cause port collisions and data corruption. Enforced by values.schema.json.
Secret
| Key | Default | Description |
|---|---|---|
secret.create | true | Create a Kubernetes Secret from secret.data |
secret.existingSecretName | "" | Reference an existing Secret instead (requires create: false) |
secret.data.OPENCLAW_GATEWAY_TOKEN | "" | Required. Auth token for health probes and non-loopback binds |
secret.data.ANTHROPIC_API_KEY | Optional. Anthropic provider key | |
secret.data.OPENAI_API_KEY | Optional. OpenAI provider key |
Add any provider API keys as additional entries under secret.data.
Persistence
| Key | Default | Description |
|---|---|---|
persistence.storageClass | "" | StorageClass name. Empty uses the cluster default |
persistence.size | 5Gi | PVC size for primary state |
persistence.accessModes | [ReadWriteOnce] | PVC access modes |
persistence.splitVolumes | false | When true, creates separate PVCs for state and workspace |
persistence.workspace.storageClass | "" | StorageClass for workspace PVC |
persistence.workspace.size | 5Gi | Workspace PVC size |
When splitVolumes is true, the state PVC mounts at /home/node/.openclaw (subPath: state) and a separate workspace PVC mounts at /home/node/.openclaw/workspace.
Config (GitOps / ConfigMode)
| Key | Default | Description |
|---|---|---|
config.desired | (see below) | JSON5 config written to openclaw.json on startup |
config.mode | merge | merge (JSON merge-patch) or overwrite (full replace) |
When config.desired is set, a ConfigMap is created and an initContainer merges or overwrites the config on the PVC before the Gateway starts. A checksum annotation triggers rollout on config changes.
Set config.desired to "" to disable config management entirely.
Default config.desired:
The chart ships with a default config that sets gateway.mode=local, gateway.bind=lan, configures the Chromium browser profile to point at the in-cluster Chromium service, routes models through the LiteLLM proxy, and creates a default agent:
config:
desired: |
{
"gateway": { "mode": "local", "bind": "lan" },
"browser": {
"enabled": true,
"defaultProfile": "default",
"profiles": {
"default": {
"cdpUrl": "http://kubeclaw-chromium:9222",
"color": "#4285F4"
}
}
},
"models": {
"mode": "merge",
"providers": {
"litellm": {
"baseUrl": "http://kubeclaw-litellm:4000",
"apiKey": "${LITELLM_API_KEY}",
"api": "openai-completions",
"models": [{ "id": "gpt-4o", ... }]
}
}
},
"agents": {
"defaults": {
"workspace": "/home/node/.openclaw/workspace",
"model": { "primary": "litellm/gpt-4o" },
"userTimezone": "UTC",
"timeoutSeconds": 600,
"maxConcurrent": 1
},
"list": [
{ "id": "main", "default": true }
]
}
}
merge applies a JSON merge-patch: objects merge recursively, arrays replace, null deletes keys. Values edited at runtime that are not in desired are preserved.
overwrite replaces the entire config file.
Node.js runtime
| Key | Default | Description |
|---|---|---|
nodeOptions | --max-old-space-size=768 | Passed as NODE_OPTIONS to every node invocation. Set to "" to suppress. |
extraEnv | [] | Extra env vars for the Gateway container (standard K8s env objects) |
Keep --max-old-space-size below your container memory limit (~75% is safe) to leave room for native allocations.
Resources
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: "1"
memory: 1Gi
Service
| Key | Default | Description |
|---|---|---|
service.type | ClusterIP | Service type |
service.port | 18789 | Port for WebSocket + HTTP Control UI |
service.annotations | {} | Extra annotations (e.g. for cloud load balancers) |
Diagnostics CronJob
| Key | Default | Description |
|---|---|---|
diagnostics.enabled | true | Enable periodic diagnostics |
diagnostics.schedule | 0 * * * * | Cron schedule (default: hourly) |
diagnostics.concurrencyPolicy | Forbid | Prevents overlapping runs |
Runs openclaw doctor --yes and openclaw status --all. Output goes to pod logs.
Pod
| Key | Default | Description |
|---|---|---|
pod.runtimeClassName | "" | RuntimeClass for gVisor/Kata isolation |
pod.annotations | {} | Extra pod annotations |
pod.labels | {} | Extra pod labels |
pod.nodeSelector | {} | Node selector |
pod.tolerations | [] | Tolerations |
pod.affinity | {} | Affinity rules |
Service account
| Key | Default | Description |
|---|---|---|
serviceAccount.create | true | Create a ServiceAccount |
serviceAccount.name | "" | Override name |
serviceAccount.annotations | {} | Annotations (e.g. for IAM roles) |
Name overrides
| Key | Default | Description |
|---|---|---|
nameOverride | "" | Override chart name |
fullnameOverride | "" | Override full release name |
If you set fullnameOverride, update litellm.environmentSecrets[0] to match: <fullname>-litellm-env.