Deploy OpenClaw on Kubernetes: Quick Start Guide
Getting AI agents to run on a cluster often feels like a chore. You usually end up fighting with complex YAML files or heavy charts just to get a single container live. If you want to get OpenClaw up and running without the headache, this guide is for you.
This is a minimal starting point for running OpenClaw on Kubernetes. It is not a production-ready setup, but it covers the core resources you need to get started.
Why not Helm?
Section titled “Why not Helm?”OpenClaw is just a single container with a few config files. Most of what you’ll want to change is the agent content—like markdown files and skills—rather than the infrastructure itself. Kustomize lets you handle these changes easily without the weight of a Helm chart. If you need more complexity later, you can always wrap these manifests in Helm.
What you need
Section titled “What you need”- A running Kubernetes cluster (AKS, EKS, GKE, k3s, kind, OpenShift, etc.)
kubectlconnected to your cluster- An API key for at least one model provider
- A container runtime like Docker or Podman
Quick start
Section titled “Quick start”# Replace with your provider: ANTHROPIC, GEMINI, OPENAI, or OPENROUTERexport <PROVIDER>_API_KEY="..."./scripts/k8s/deploy.sh
kubectl port-forward svc/openclaw 18789:18789 -n openclawopen http://localhost:18789Grab your gateway token and put it into the Control UI:
kubectl get secret openclaw-secrets -n openclaw -o jsonpath='{.data.OPENCLAW_GATEWAY_TOKEN}' | base64 -dIf you are debugging locally, you can use ./scripts/k8s/deploy.sh --show-token to see the token right after you deploy.
Local testing with Kind
Section titled “Local testing with Kind”If you don’t have a cluster ready, you can spin one up locally using Kind:
./scripts/k8s/create-kind.sh # auto-detects docker or podman./scripts/k8s/create-kind.sh --delete # tear downAfter that, just run the deploy script like normal with ./scripts/k8s/deploy.sh.
Step by step
Section titled “Step by step”1) Deploy
Section titled “1) Deploy”Option A — Put your API key in the environment (one step):
# Replace with your provider: ANTHROPIC, GEMINI, OPENAI, or OPENROUTERexport <PROVIDER>_API_KEY="..."./scripts/k8s/deploy.shThis script sets up a Kubernetes Secret with your API key and a token. It then handles the deployment. If the Secret is already there, it keeps your existing token and any other provider keys you haven’t changed.
Option B — Create the secret separately:
export <PROVIDER>_API_KEY="..."./scripts/k8s/deploy.sh --create-secret./scripts/k8s/deploy.shUse the --show-token flag with these commands if you want the token to show up in your terminal for local testing.
2) Access the gateway
Section titled “2) Access the gateway”kubectl port-forward svc/openclaw 18789:18789 -n openclawopen http://localhost:18789What gets deployed
Section titled “What gets deployed”Namespace: openclaw (configurable via OPENCLAW_NAMESPACE)├── Deployment/openclaw # Single pod, init container + gateway├── Service/openclaw # ClusterIP on port 18789├── PersistentVolumeClaim # 10Gi for agent state and config├── ConfigMap/openclaw-config # openclaw.json + AGENTS.md└── Secret/openclaw-secrets # Gateway token + API keysCustomization
Section titled “Customization”Agent instructions
Section titled “Agent instructions”Update the AGENTS.md file inside scripts/k8s/manifests/configmap.yaml and run the deploy script again:
./scripts/k8s/deploy.shGateway config
Section titled “Gateway config”You can edit openclaw.json in scripts/k8s/manifests/configmap.yaml. Check out the Gateway configuration for all the details.
Add providers
Section titled “Add providers”Run the script again with your new keys:
export ANTHROPIC_API_KEY="..."export OPENAI_API_KEY="..."./scripts/k8s/deploy.sh --create-secret./scripts/k8s/deploy.shYour existing keys stay in the Secret unless you choose to overwrite them. You can also patch the Secret directly:
kubectl patch secret openclaw-secrets -n openclaw \ -p '{"stringData":{"<PROVIDER>_API_KEY":"..."}}'kubectl rollout restart deployment/openclaw -n openclawCustom namespace
Section titled “Custom namespace”OPENCLAW_NAMESPACE=my-namespace ./scripts/k8s/deploy.shCustom image
Section titled “Custom image”Change the image field in scripts/k8s/manifests/deployment.yaml:
image: ghcr.io/openclaw/openclaw:2026.3.1Expose beyond port-forward
Section titled “Expose beyond port-forward”The default setup binds the gateway to loopback inside the pod. This is great for kubectl port-forward, but it won’t work if you want to use a Kubernetes Service or Ingress to reach the pod IP.
- Change the gateway bind in
scripts/k8s/manifests/configmap.yamlto a non-loopback address that fits your deployment. - Keep gateway auth on and use a proper TLS-terminated entrypoint.
- Set up the Control UI for remote access with the right security settings and allowed origins.
Re-deploy
Section titled “Re-deploy”./scripts/k8s/deploy.shThis applies your changes and restarts the pod so it sees the new config or secret updates.
Teardown
Section titled “Teardown”./scripts/k8s/deploy.sh --deleteThis wipes the namespace and everything in it, including your storage (PVC).
Architecture notes
Section titled “Architecture notes”- The gateway uses a loopback bind by default, so use
kubectl port-forwardfor the included setup. - Everything stays inside a single namespace; there are no cluster-wide resources.
- Security is built-in:
readOnlyRootFilesystem,drop: ALLcapabilities, and it runs as a non-root user (UID 1000). - The setup keeps the Control UI on a local-access path for safety.
- If you move to remote access, use HTTPS or Tailscale and update your gateway bind settings.
- Secrets are handled in a temporary directory and sent to the cluster, so no sensitive data stays in your local files.
File structure
Section titled “File structure”scripts/k8s/├── deploy.sh # Creates namespace + secret, deploys via kustomize├── create-kind.sh # Local Kind cluster (auto-detects docker/podman)└── manifests/ ├── kustomization.yaml # Kustomize base ├── configmap.yaml # openclaw.json + AGENTS.md ├── deployment.yaml # Pod spec with security hardening ├── pvc.yaml # 10Gi persistent storage └── service.yaml # ClusterIP on 18789OpenClaw Expert
Still stuck?
If this page didn't answer your case, ask OpenClaw Expert for step-by-step guidance.