Skip to content

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.

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.

  • A running Kubernetes cluster (AKS, EKS, GKE, k3s, kind, OpenShift, etc.)
  • kubectl connected to your cluster
  • An API key for at least one model provider
  • A container runtime like Docker or Podman
Terminal window
# Replace with your provider: ANTHROPIC, GEMINI, OPENAI, or OPENROUTER
export <PROVIDER>_API_KEY="..."
./scripts/k8s/deploy.sh
kubectl port-forward svc/openclaw 18789:18789 -n openclaw
open http://localhost:18789

Grab your gateway token and put it into the Control UI:

Terminal window
kubectl get secret openclaw-secrets -n openclaw -o jsonpath='{.data.OPENCLAW_GATEWAY_TOKEN}' | base64 -d

If you are debugging locally, you can use ./scripts/k8s/deploy.sh --show-token to see the token right after you deploy.

If you don’t have a cluster ready, you can spin one up locally using Kind:

Terminal window
./scripts/k8s/create-kind.sh # auto-detects docker or podman
./scripts/k8s/create-kind.sh --delete # tear down

After that, just run the deploy script like normal with ./scripts/k8s/deploy.sh.

Option A — Put your API key in the environment (one step):

Terminal window
# Replace with your provider: ANTHROPIC, GEMINI, OPENAI, or OPENROUTER
export <PROVIDER>_API_KEY="..."
./scripts/k8s/deploy.sh

This 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:

Terminal window
export <PROVIDER>_API_KEY="..."
./scripts/k8s/deploy.sh --create-secret
./scripts/k8s/deploy.sh

Use the --show-token flag with these commands if you want the token to show up in your terminal for local testing.

Terminal window
kubectl port-forward svc/openclaw 18789:18789 -n openclaw
open http://localhost:18789
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 keys

Update the AGENTS.md file inside scripts/k8s/manifests/configmap.yaml and run the deploy script again:

Terminal window
./scripts/k8s/deploy.sh

You can edit openclaw.json in scripts/k8s/manifests/configmap.yaml. Check out the Gateway configuration for all the details.

Run the script again with your new keys:

Terminal window
export ANTHROPIC_API_KEY="..."
export OPENAI_API_KEY="..."
./scripts/k8s/deploy.sh --create-secret
./scripts/k8s/deploy.sh

Your existing keys stay in the Secret unless you choose to overwrite them. You can also patch the Secret directly:

Terminal window
kubectl patch secret openclaw-secrets -n openclaw \
-p '{"stringData":{"<PROVIDER>_API_KEY":"..."}}'
kubectl rollout restart deployment/openclaw -n openclaw
Terminal window
OPENCLAW_NAMESPACE=my-namespace ./scripts/k8s/deploy.sh

Change the image field in scripts/k8s/manifests/deployment.yaml:

image: ghcr.io/openclaw/openclaw:2026.3.1

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.yaml to 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.
Terminal window
./scripts/k8s/deploy.sh

This applies your changes and restarts the pod so it sees the new config or secret updates.

Terminal window
./scripts/k8s/deploy.sh --delete

This wipes the namespace and everything in it, including your storage (PVC).

  • The gateway uses a loopback bind by default, so use kubectl port-forward for the included setup.
  • Everything stays inside a single namespace; there are no cluster-wide resources.
  • Security is built-in: readOnlyRootFilesystem, drop: ALL capabilities, 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.
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 18789

AI Setup Assistant

OpenClaw

OpenClaw Expert

Still stuck?

If this page didn't answer your case, ask OpenClaw Expert for step-by-step guidance.