Self-Host OpenClaw on Kubernetes
This guide walks you through deploying OpenClaw on a Kubernetes cluster using Kustomize. The deployment creates a single-pod setup with an init container, gateway service, persistent storage, and configurable agent instructions. It works on any conformant Kubernetes cluster, whether managed (EKS, GKE, AKS) or self-hosted.
Quick Path
For experienced Kubernetes operators who want to get running fast:
- Clone the OpenClaw repository and
cdintodeploy/kubernetes/ - Export your LLM API key:
export ANTHROPIC_API_KEY=sk-... - Generate secrets:
./scripts/generate-secrets.sh - Review and edit
config/openclaw.jsonandconfig/AGENTS.md - Deploy:
kubectl apply -k . - Port-forward:
kubectl port-forward -n openclaw svc/openclaw-gateway 18789:18789 - Open
http://localhost:18789in your browser
Prerequisites
Before you begin, make sure you have:
- A running Kubernetes cluster (v1.24+)
kubectlconfigured and pointing at your cluster- An API key from your chosen LLM provider (Anthropic, OpenAI, or OpenRouter)
opensslor another tool for generating random tokens
If you want to test locally before deploying to a real cluster, see the "Local Development with Kind" section at the end of this guide.
Architecture Overview
The Kustomize deployment creates the following resources in a dedicated openclaw namespace:
- Namespace — isolates all OpenClaw resources
- Deployment — single-pod with an init container that prepares configuration, plus the main gateway container
- Service — ClusterIP service exposing port 18789 internally
- PersistentVolumeClaim — 10GB volume for workspace data, agent state, and configuration
- ConfigMap — holds
openclaw.json(runtime config) andAGENTS.md(agent instructions) - Secret — stores the gateway token and LLM provider API keys
Step-by-Step Deployment
Clone the Repository
Configure Your API Keys
Generate a gateway token and set your LLM provider key:
Create the Kubernetes secret from these values:
If you use a different provider, substitute the appropriate key name (e.g., openai-api-key, openrouter-api-key).
Review the Configuration
The ConfigMap sources live in the config/ directory:
Edit config/openclaw.json to set your preferred model and runtime options:
Edit config/AGENTS.md to customize the system prompt and agent behavior:
Review the Kustomize Manifests
The kustomization.yaml ties everything together:
The deployment manifest defines the pod:
The PVC requests 10GB of storage:
The Service exposes the gateway on ClusterIP:
Deploy
Apply the full stack with a single command:
Verify the pod is running:
Wait until the pod shows Running with 1/1 ready containers.
Access the Gateway
Port-forward the service to your local machine:
Open http://localhost:18789 in your browser. Use the gateway token you generated earlier to authenticate.
Customization
Pinning the Container Image
For reproducible deployments, pin to a specific image tag instead of latest:
Check the OpenClaw releases page for available tags.
Adding Model Providers
To add OpenAI or OpenRouter alongside Anthropic, extend the secret:
Then add the corresponding env entries in the deployment manifest.
Custom Namespace
Change the namespace in kustomization.yaml:
All resources will be created in the new namespace automatically.
Ingress for Remote Access
To expose OpenClaw outside the cluster, create an Ingress resource:
This requires an Ingress controller (nginx, Traefik, etc.) and cert-manager for automatic TLS certificates.
Security Best Practices
- Bind to loopback by default. The gateway configuration defaults to
127.0.0.1. Only change to0.0.0.0inside the pod where the Service handles external routing. - Always use TLS for remote access. If you expose the gateway via Ingress, use cert-manager or your cloud provider's TLS termination. Never send the gateway token over plain HTTP.
- Rotate the gateway token periodically. Update the secret and restart the pod.
- Use Kubernetes RBAC. Restrict who can read the
openclaw-secretsSecret in your cluster. - Consider Tailscale or a VPN for accessing the gateway without a public Ingress. Install the Tailscale sidecar container to join your tailnet.
- Network policies. If your cluster supports them, restrict egress from the OpenClaw pod to only the LLM provider endpoints and your code repositories.
Local Development with Kind
To test the deployment locally before pushing to a production cluster:
Delete the cluster when done:
Troubleshooting
Pod stuck in Pending
Check if the PVC is bound:
If the PVC is stuck in Pending, your cluster may not have a default StorageClass. Create one or specify a storageClassName in the PVC manifest.
Init container fails
Inspect the init container logs:
Common cause: the ConfigMap was not created because kustomize was not used (plain kubectl apply -f skips configMapGenerator).
Gateway returns 401 Unauthorized
Verify the token matches what you generated:
Container OOMKilled
Increase the memory limit in the deployment manifest. If you are running large context windows or multiple concurrent sessions, bump to 2Gi or higher.
Persistent data missing after pod restart
Confirm the PVC is attached and the volume mount paths are correct. Data should survive pod restarts as long as the PVC is not deleted.
Updating OpenClaw
To update to a new version:
Kubernetes performs a rolling update by default, so there is minimal downtime.