Platform setup

How to Deploy OpenClaw on Kubernetes

4 min read

Browse more in Platform setup.

All platform setup guides →

This guide walks you through how to deploy OpenClaw on Kubernetes using the official kustomize-based manifests and helper scripts. You’ll go from a bare cluster to a running OpenClaw gateway reachable via kubectl port-forward, with secrets and persistent storage wired up.

By the end, you’ll know how to customize agents, gateway config, providers, namespaces, and images for your own cluster.

Setup flow

Prerequisites

  • 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 (ANTHROPIC, GEMINI, OPENAI, or OPENROUTER).

Steps

  1. 1

    Create a local Kind cluster for testing (optional)

    If you don’t already have a Kubernetes cluster, you can spin up a local one with Kind using the helper script. This is useful to validate your OpenClaw manifests before touching a shared or production cluster.

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

    Export your model provider API key

    OpenClaw needs at least one model provider key to start doing useful work. Export the provider-specific API key in your shell so the deploy script can create or update the Kubernetes Secret correctly.

    bash
    # Replace with your provider: ANTHROPIC, GEMINI, OPENAI, or OPENROUTER
    export <PROVIDER>_API_KEY="..."
  3. 3

    Deploy OpenClaw with the helper script

    Use the deploy script to create the namespace, secrets, and core resources via kustomize. Option A is the simplest path, while Option B gives you an explicit secret-creation step if you want more control over when secrets change.

    bash
    # Option A — API key in environment (one step):
    # Replace with your provider: ANTHROPIC, GEMINI, OPENAI, or OPENROUTER
    export <PROVIDER>_API_KEY="..."
    ./scripts/k8s/deploy.sh
    
    # Option B — create the secret separately:
    export <PROVIDER>_API_KEY="..."
    ./scripts/k8s/deploy.sh --create-secret
    ./scripts/k8s/deploy.sh
  4. 4

    Retrieve the gateway token for the Control UI

    The deploy script sets up token-based auth for the gateway by default, so you need the generated token to log into the Control UI. You can either print it directly during deploy for local debugging or read it from the Kubernetes Secret afterward.

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

    Access the OpenClaw gateway via port-forward

    By default the gateway binds to loopback inside the pod, so you reach it using kubectl port-forward from your machine. This keeps the Control UI on a safer local-access path while you experiment.

    bash
    kubectl port-forward svc/openclaw 18789:18789 -n openclaw
    open http://localhost:18789
  6. 6

    Customize agents and gateway configuration

    Once the base deployment works, you can edit the agent instructions and gateway config baked into the ConfigMap. json in the manifests, re-run the deploy script so Kubernetes picks up the new configuration.

    bash
    ## Edit AGENTS.md in scripts/k8s/manifests/configmap.yaml, then:
    ./scripts/k8s/deploy.sh
  7. 7

    Add additional model providers

    You can enable multiple providers by exporting more API keys and recreating the secret. The script preserves existing provider keys unless you overwrite them, so you can safely add providers incrementally.

    bash
    export ANTHROPIC_API_KEY="..."
    export OPENAI_API_KEY="..."
    ./scripts/k8s/deploy.sh --create-secret
    ./scripts/k8s/deploy.sh
  8. 8

    Use a custom namespace or image when needed

    If you don’t want to deploy into the default openclaw namespace or you need to pin a specific image, the manifests support both. Set OPENCLAW_NAMESPACE inline when running the deploy script, and edit the image field in the deployment manifest when you want to change the container image.

    bash
    OPENCLAW_NAMESPACE=my-namespace ./scripts/k8s/deploy.sh
    
    # In scripts/k8s/manifests/deployment.yaml
    image: ghcr.io/openclaw/openclaw:latest # or pin to a specific version from https://github.com/openclaw/openclaw/releases
  9. 9

    Tear down the OpenClaw namespace when you’re done

    When you want to remove OpenClaw from the cluster, use the delete flag on the deploy script. This cleans up the namespace and all resources in it, including the persistent volume claim.

    bash
    ./scripts/k8s/deploy.sh --delete

Configuration

OptionDescriptionExample
<PROVIDER>_API_KEYAPI key for a supported model provider such as ANTHROPIC, GEMINI, OPENAI, or OPENROUTER; used by the deploy script to populate the Kubernetes Secret.ANTHROPIC_API_KEY
ANTHROPIC_API_KEYAnthropic provider API key stored in the openclaw-secrets Secret for Anthropic-backed models.ANTHROPIC_API_KEY="sk-ant-api03-..."
OPENAI_API_KEYOpenAI provider API key stored in the openclaw-secrets Secret for OpenAI-backed models.OPENAI_API_KEY="sk-openai-..."
OPENCLAW_NAMESPACEOverrides the default Kubernetes namespace (openclaw) where all OpenClaw resources are created.OPENCLAW_NAMESPACE=my-namespace
OPENCLAW_GATEWAY_TOKENShared secret used for gateway token auth, stored in the openclaw-secrets Secret and required by the Control UI.OPENCLAW_GATEWAY_TOKEN="long-random-token"

Troubleshooting

You can’t reach the Control UI through a Service or Ingress even though the pod is running.

The gateway binds to loopback inside the pod by default, which only works with kubectl port-forward. yaml from loopback to a non-loopback bind that matches your deployment model, then redeploy and expose it through an Ingress or load balancer.

bash
./scripts/k8s/deploy.sh

After adding a new provider API key, OpenClaw still behaves as if the provider is missing.

The running pod may still use the old Secret data. Re-run the deploy script with --create-secret to update the Secret, then redeploy so the pod picks up the new keys, or patch the Secret directly and restart the deployment.

bash
kubectl patch secret openclaw-secrets -n openclaw \
  -p '{"stringData":{"<PROVIDER>_API_KEY":"..."}}'
kubectl rollout restart deployment/openclaw -n openclaw

You forgot the gateway token and can’t authenticate to the Control UI.

The deploy script stores the token in the openclaw-secrets Secret. Retrieve it by reading the OPENCLAW_GATEWAY_TOKEN field and decoding it from base64.

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

You want to reset everything, including persistent data, but resources still linger in the cluster.

Use the deploy script with the --delete flag to remove the namespace and all resources, including the PVC. This gives you a clean slate for a fresh deployment.

bash
./scripts/k8s/deploy.sh --delete

Frequently asked questions

Powered by Mem0

Add persistent memory to OpenClaw

Official Mem0 plugin for OpenClaw keeps context across chats and tools. Smaller prompts, lower cost, better continuity for your agents.

More in Platform setup