Skip to main content
Before you start, you should be familiar with:
  • Basic Kubernetes usage (kubectl, Namespace, Deployment, Service, PVC)
  • How to configure inter-container networking and persistent storage
The LangBot repository ships a ready-to-use Kubernetes manifest at docker/kubernetes.yaml. This page is the deployment guide for that manifest, focusing on the Box sandbox runtime under Kubernetes — the part that differs most from the Docker Compose deployment.

Components

The manifest creates the following components in the langbot namespace:
ComponentDescriptionPorts
langbotMain app (WebUI + webhooks)5300 / 2280-2290
langbot-plugin-runtimePlugin runtime5400
langbot-boxBox sandbox runtime (optional)5410
Persistent storage: three PVCs (langbot-data, langbot-plugins, langbot-plugin-runtime-data). The Box workspace root uses a node hostPath (/app/data/box) rather than a PVC.

Quick Start

# Clone the repository
git clone https://github.com/langbot-app/LangBot
cd LangBot/docker

# Deploy all components
kubectl apply -f kubernetes.yaml

# Check status
kubectl get all -n langbot
Access the WebUI via port-forward:
kubectl port-forward -n langbot svc/langbot 5300:5300
# Visit http://localhost:5300
For production, expose via Ingress + TLS (the manifest already includes commented Ingress / LoadBalancer / NodePort examples — uncomment as needed).

Box Sandbox Runtime

langbot-box provides the code-sandbox capability backing the sandbox tools (exec / read / write / edit / glob / grep), the skill activate tool and skill add/edit, and stdio-mode MCP servers. It is optional: without it, LangBot still runs and the dashboard / skills list stay visible (read-only), but those features are disabled — in that case set BOX__ENABLED=false on langbot.

How it works & the key constraint

The official LangBot image ships only the Docker CLI (no dockerd, no nsjail). The Box runtime therefore creates sandbox containers by talking to the node’s Docker daemon over the mounted socket (/var/run/docker.sock) — it does not run dockerd inside the Pod. This imposes a key constraint: the daemon that actually creates sandbox containers is the node’s Docker daemon, which resolves bind-mount paths against the node filesystem. So the Box workspace root must be the same absolute path in all three places:
  1. The actual path on the node
  2. The mount path inside the langbot-box container
  3. The mount path inside every sandbox container it spawns
This is exactly why the manifest uses a hostPath (fixed at /app/data/box) instead of a regular PVC: a PVC path only exists inside the Pod’s mount namespace, which the node’s dockerd cannot see. langbot and langbot-box are also pinned to the same node via podAffinity so they share this hostPath.
Because it relies on hostPath + same-node affinity, langbot does not support multi-replica horizontal scaling (same limitation as ReadWriteOnce PVCs). High availability requires a different architecture.

Connection & configuration

  • langbot connects to the Box runtime over WebSocket, using the endpoint from the ConfigMap: BOX__RUNTIME__ENDPOINT: ws://langbot-box:5410.
The in-container default hostname is langbot_box (with an underscore), which is not a valid Kubernetes DNS name. The endpoint must therefore be set explicitly to the valid Service name langbot-box — you cannot rely on the in-container default.
  • The Box runtime does not read its own box.local.* / BOX__* environment variables; its configuration is read from BOX__LOCAL__* by langbot and pushed via the INIT RPC. So BOX__LOCAL__HOST_ROOT / DEFAULT_WORKSPACE / SKILLS_ROOT / ALLOWED_MOUNT_ROOTS are set on the langbot Deployment, where HOST_ROOT must match the box-root mountPath on both sides (/app/data/box).

Security note

Mounting the node’s Docker socket grants the Box runtime (and any code executed in the sandbox) effective root on the node. Only deploy Box on nodes you trust for this workload — ideally a dedicated node pool isolated with taints/tolerations. For a stronger isolation boundary, switch box.backend to e2b (set E2B_API_KEY) and drop the docker.sock mount + hostPath. See Sandbox configuration.

Verify Box is ready

# Box runtime logs (should show the selected backend, e.g. "using backend: docker")
kubectl logs -n langbot -l app=langbot-box -f

# Confirm langbot connected to the Box runtime
kubectl logs -n langbot -l app=langbot | grep -i "box runtime"

When you don’t need the sandbox

If you do not need the sandbox, remove the langbot-box Deployment / Service from the manifest and set BOX__ENABLED=false on the langbot Deployment to avoid connection-failure warnings in the logs.

Further reading