Skip to main content

Kind provisioner backend

Local-only Kubernetes provisioner for development and CI. Not for production.
Kind (“Kubernetes in Docker”) is for local testing only. Do not run production agents on a Kind cluster — it has no persistence guarantees, no load-balancer integration, and no high availability. For a self-hosted production cluster use K3s; for managed control planes use AKS, GKE, or EKS.
Kind uses the same generic k8s backend id as every Kubernetes provider. Nora ships a single Kubernetes adapter (workers/provisioner/backends/k8s.ts) that serves Kind, K3s, AKS, GKE, and EKS — only the kubeconfig and exposure mode change.

When to use Kind

  • Local development of Nora itself, or local exercise of the Kubernetes adapter on a laptop.
  • CI smoke runs that need a real Kubernetes API without a cloud account.
  • Quick regression checks before promoting changes to a K3s or cloud cluster.
Do not use Kind for:
  • Hosting agents you depend on — Kind clusters live and die with the local Docker daemon.
  • Modeling cloud LoadBalancer behavior — Kind only supports NodePort routing in this overlay.
  • Multi-node or multi-host scheduling — the bundled Kind config is single control-plane.

Step-by-step setup

1. Prerequisites

docker --version && docker compose version
kubectl version --client
kind itself is auto-installed by e2e/scripts/ensure-kind-tools.sh when the smoke script runs.

2. Run the smoke script

The recommended path is the bundled smoke. It creates or reuses a Kind cluster, exports kubeconfigs for both the host and the in-container view, starts the Nora API and provisioner with docker-compose.kubernetes.yml plus the Kind network helper, registers the cluster in Admin, deploys an agent, verifies Kubernetes objects, and exercises stop/start/restart lifecycle.
cd e2e
npm run smoke:k8s-kind
Set KEEP_ENV=true to leave the cluster and Compose stack running after the script finishes.

3. Inspect the deployed agent in the Nora UI

With KEEP_ENV=true, open the dashboard at the API base URL the smoke script prints (defaults to http://127.0.0.1:4110) and pick a deployed agent from the fleet view to see its Kubernetes-flavored detail page.
Deploy wizard backend
picker
Deploy wizard Kubernetes
selected
Agent detail K8s

Manual stack (without the smoke script)

export NORA_KUBECONFIGS_DIR=/tmp
docker compose -f docker-compose.yml -f docker-compose.kubernetes.yml -f docker-compose.kind.yml up -d --build
Then register the Kind cluster in Admin -> Kubernetes:
FieldValue
Credential modeMounted kubeconfig path
Kubeconfig path/kubeconfigs/nora-kind.container.kubeconfig
Exposure modeNodePort
Runtime hosthost.docker.internal, or the Kind control-plane container name on Linux
Runtime node port30909
Gateway node port31879
The Admin Runtime host must be reachable from the Compose containers. On Linux without host.docker.internal support, set it to the Kind control-plane container name (nora-kind-control-plane by default) and join the kind Docker network.

Register local Kind in Admin

Open Admin -> Kubernetes, click Add cluster, and use these values:
FieldValue
Cluster idkind-local
LabelKind Local
ProviderGeneric Kubernetes
Actual cluster nameThe Kind cluster name, for example nora-kind
Credential modeMounted kubeconfig path
Kubeconfig path/kubeconfigs/nora-kind.container.kubeconfig
Fallback namespaceopenclaw-agents
OpenClaw namespaceopenclaw-agents
Hermes namespaceopenclaw-agents
Exposure modeNodePort
Runtime hosthost.docker.internal, or the Kind control-plane container name on Linux if you joined the kind Docker network
Runtime node port30909 for the bundled Kind overlay
Gateway node port31879 for the bundled Kind overlay
Do not put /tmp/nora-kind.container.kubeconfig in the Admin Kubeconfig path when Nora runs in Docker Compose. That is the host-side CONTAINER_KUBECONFIG_PATH; the containers see it under /kubeconfigs.

Verification

kubectl -n openclaw-agents get deploy,svc,pods
docker compose -f docker-compose.yml -f docker-compose.kubernetes.yml -f docker-compose.kind.yml logs worker-provisioner
The smoke script exits with {"ok":true,...} on success. Per-agent objects follow the generated naming convention nora-oclaw-<agent-name>-<suffix> in the openclaw-agents namespace. If the agent reaches running but the gateway is unreachable, confirm the NodePort values match the port mappings in infra/kind/nora-kind.yaml.
Agent logs K8s

See also

  • K3s — self-hosted production K8s
  • AKS — Azure Kubernetes Service
  • GKE — Google Kubernetes Engine
  • EKS — Amazon EKS