Deploy OpenClaw with Helm

Install OpenClaw on any Kubernetes cluster using Helm charts. Covers EKS, GKE, AKS with autoscaling, secrets management, and Ingress.

Platform: Kubernetes
Cost: $50-200/month
Time: 30 minutes
Difficulty: Intermediate

Deploy OpenClaw with Helm on Kubernetes

Deploy OpenClaw to any Kubernetes cluster using Helm. This guide covers installation, configuration, scaling, and production best practices for EKS, GKE, AKS, and self-managed clusters.

Prerequisites

  • Kubernetes cluster (1.24+) — EKS, GKE, AKS, or self-managed
  • kubectl configured and connected to your cluster
  • Helm v3 installed
  • An API key from Anthropic or OpenAI

Quick Start

Add the OpenClaw Helm repository

helm repo add openclaw https://charts.openclaw.ai
helm repo update

Install OpenClaw

# Create a namespace
kubectl create namespace openclaw

# Install with default values
helm install openclaw openclaw/openclaw \
  --namespace openclaw \
  --set config.anthropicApiKey="sk-ant-..."

That's it. OpenClaw is now running on your cluster.

Verify the deployment

kubectl get pods -n openclaw
kubectl logs -n openclaw deployment/openclaw

Configuration

Using a values file

Create values.yaml:

# values.yaml
replicaCount: 2

image:
  repository: ghcr.io/openclaw/openclaw
  tag: latest
  pullPolicy: IfNotPresent

config:
  # LLM Provider (required)
  anthropicApiKey: ""  # Or use existingSecret
  # openaiApiKey: ""
  
  # Model configuration
  model: claude-sonnet-4-20250514
  
  # Gateway settings
  port: 8789
  logLevel: info

# Use an existing secret for API keys (recommended for production)
existingSecret:
  name: openclaw-secrets
  anthropicApiKeyKey: ANTHROPIC_API_KEY

# Resource limits
resources:
  requests:
    cpu: 100m
    memory: 256Mi
  limits:
    cpu: 1000m
    memory: 1Gi

# Horizontal Pod Autoscaler
autoscaling:
  enabled: true
  minReplicas: 2
  maxReplicas: 10
  targetCPUUtilizationPercentage: 70

# Persistence for workspace/memory
persistence:
  enabled: true
  storageClass: ""  # Uses default if empty
  size: 5Gi

# Ingress configuration
ingress:
  enabled: true
  className: nginx
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
  hosts:
    - host: openclaw.example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: openclaw-tls
      hosts:
        - openclaw.example.com

# Service configuration
service:
  type: ClusterIP
  port: 8789

# Pod security
podSecurityContext:
  runAsNonRoot: true
  runAsUser: 1000
  fsGroup: 1000

securityContext:
  allowPrivilegeEscalation: false
  readOnlyRootFilesystem: true
  capabilities:
    drop:
      - ALL

Install with your values:

helm install openclaw openclaw/openclaw \
  --namespace openclaw \
  --values values.yaml

Secrets Management

Option 1: Helm values (simple, not recommended for production)

helm install openclaw openclaw/openclaw \
  --set config.anthropicApiKey="sk-ant-..."

Option 2: Kubernetes Secret (recommended)

Create the secret:

kubectl create secret generic openclaw-secrets \
  --namespace openclaw \
  --from-literal=ANTHROPIC_API_KEY="sk-ant-..."

Reference it in values:

existingSecret:
  name: openclaw-secrets
  anthropicApiKeyKey: ANTHROPIC_API_KEY

Option 3: External Secrets Operator

For production, use External Secrets with AWS Secrets Manager, HashiCorp Vault, etc.:

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: openclaw-secrets
  namespace: openclaw
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: aws-secrets-manager
    kind: ClusterSecretStore
  target:
    name: openclaw-secrets
  data:
    - secretKey: ANTHROPIC_API_KEY
      remoteRef:
        key: openclaw/api-keys
        property: anthropic

Scaling

Horizontal Pod Autoscaler (HPA)

Enable autoscaling in values:

autoscaling:
  enabled: true
  minReplicas: 2
  maxReplicas: 10
  targetCPUUtilizationPercentage: 70
  targetMemoryUtilizationPercentage: 80

Manual scaling

kubectl scale deployment openclaw --replicas=5 -n openclaw

Pod Disruption Budget

The chart includes a PDB for high availability:

podDisruptionBudget:
  enabled: true
  minAvailable: 1

Ingress Configuration

NGINX Ingress

ingress:
  enabled: true
  className: nginx
  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: "50m"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
  hosts:
    - host: openclaw.example.com
      paths:
        - path: /
          pathType: Prefix

AWS ALB Ingress

ingress:
  enabled: true
  className: alb
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:...
  hosts:
    - host: openclaw.example.com
      paths:
        - path: /
          pathType: Prefix

GKE Ingress

ingress:
  enabled: true
  className: gce
  annotations:
    kubernetes.io/ingress.global-static-ip-name: openclaw-ip
    networking.gke.io/managed-certificates: openclaw-cert
  hosts:
    - host: openclaw.example.com
      paths:
        - path: /
          pathType: Prefix

Persistence

OpenClaw stores workspace files and memory in a persistent volume:

persistence:
  enabled: true
  storageClass: gp3  # AWS EBS
  # storageClass: premium-rwo  # GKE
  # storageClass: managed-premium  # AKS
  size: 10Gi
  accessMode: ReadWriteOnce

Shared storage (multi-replica)

For multiple replicas sharing state, use ReadWriteMany storage:

persistence:
  enabled: true
  storageClass: efs  # AWS EFS
  # storageClass: filestore  # GKE Filestore
  size: 10Gi
  accessMode: ReadWriteMany

Monitoring

Prometheus metrics

Enable the metrics endpoint:

metrics:
  enabled: true
  port: 9090
  serviceMonitor:
    enabled: true
    interval: 30s

Grafana dashboard

Import the OpenClaw dashboard from the chart:

kubectl get configmap -n openclaw openclaw-grafana-dashboard -o jsonpath='{.data.dashboard\.json}' > dashboard.json

Upgrading

Check available versions

helm search repo openclaw --versions

Upgrade to latest

helm repo update
helm upgrade openclaw openclaw/openclaw \
  --namespace openclaw \
  --values values.yaml

Upgrade to specific version

helm upgrade openclaw openclaw/openclaw \
  --namespace openclaw \
  --values values.yaml \
  --version 1.2.0

Uninstalling

helm uninstall openclaw --namespace openclaw

# Optional: Remove the namespace and PVCs
kubectl delete namespace openclaw

Troubleshooting

Pod not starting

kubectl describe pod -n openclaw -l app.kubernetes.io/name=openclaw
kubectl logs -n openclaw -l app.kubernetes.io/name=openclaw --previous

API key issues

# Verify the secret exists and has the right key
kubectl get secret openclaw-secrets -n openclaw -o yaml

# Check environment variables in the pod
kubectl exec -n openclaw deployment/openclaw -- env | grep -i api

Ingress not working

kubectl describe ingress -n openclaw
kubectl get events -n openclaw

Persistent volume issues

kubectl get pvc -n openclaw
kubectl describe pvc -n openclaw openclaw-workspace

Production Checklist

  • Use existingSecret for API keys, not plain values
  • Enable autoscaling with appropriate min/max replicas
  • Configure podDisruptionBudget for HA
  • Set resource requests and limits
  • Enable persistence with appropriate storage class
  • Configure Ingress with TLS
  • Enable Prometheus metrics and alerts
  • Set up log aggregation (Loki, CloudWatch, etc.)
  • Test disaster recovery / backup restore

Chart Values Reference

ParameterDescriptionDefault
replicaCountNumber of replicas1
image.repositoryImage repositoryghcr.io/openclaw/openclaw
image.tagImage taglatest
config.anthropicApiKeyAnthropic API key""
config.modelLLM modelclaude-sonnet-4-20250514
existingSecret.nameName of existing secret""
autoscaling.enabledEnable HPAfalse
persistence.enabledEnable PVCtrue
persistence.sizePVC size5Gi
ingress.enabledEnable Ingressfalse

See the full values.yaml for all options.


Need help? Join our Discord or open an issue on GitHub.