Agent Sandbox
Pi Code Agent Sandbox Example
This example demonstrates how to run Pi — a terminal-based coding agent from Earendil Works — inside a Kubernetes cluster using the Sandbox CRD from agent-sandbox.
It mirrors Pi’s Plain Docker containerization pattern, adapted to the Sandbox CRD.
Prerequisites
- A Kubernetes cluster (Kind, Minikube, GKE, etc.).
agent-sandboxcontroller and CRDs installed in the cluster.kubectlconfigured to access your cluster.- Docker (for building the Pi image locally).
- (If using Kind) Kind installed.
- An Anthropic API key.
Files
Dockerfile: Buildspi-sandbox:localfromnode:24-bookworm-slim, installing@earendil-works/pi-coding-agent@0.84.1.sandbox.yaml: TheSandboxmanifest. Two PVCs (/workspacefor code,/root/.pi/agentfor Pi’s own settings/sessions),ANTHROPIC_API_KEYinjected from a Secret,stdin/ttyenabled so you can attach to the Pi TUI.run-test-kind.sh: Build, load into Kind, apply, and wait — one command end-to-end.
How to Use
1. Create the API key Secret
kubectl create secret generic pi-code-agent-api-keys \
--from-literal=ANTHROPIC_API_KEY="your_anthropic_key"
2. Deploy the Sandbox
Option A: Quick path (Kind)
./run-test-kind.sh
This builds the image, loads it into the Kind cluster (default name agent-sandbox, override with KIND_CLUSTER_NAME=...), applies sandbox.yaml, and waits for the pod to become Ready.
Option B: Manual path
# Build the image
docker build -t pi-sandbox:local .
# Apply the Sandbox manifest
kubectl apply -f sandbox.yaml
Kind users — load the image into the cluster before applying the manifest (or use ./run-test-kind.sh, which does this for you):
kind load docker-image pi-sandbox:local --name "${KIND_CLUSTER_NAME:-agent-sandbox}"
Non-Kind clusters (Minikube, GKE, EKS, …) — sandbox.yaml references pi-sandbox:local, which is a node-local image. For clusters that cannot see your local Docker daemon, push the image to a registry and update the image: field in sandbox.yaml before applying:
# Example: push to a registry you control
docker tag pi-sandbox:local REGISTRY/pi-sandbox:0.84.1
docker push REGISTRY/pi-sandbox:0.84.1
# Edit sandbox.yaml: replace `image: pi-sandbox:local` with `image: REGISTRY/pi-sandbox:0.84.1`
kubectl apply -f sandbox.yaml
3. Verify the Deployment
kubectl get sandboxes
kubectl get pods -l sandbox=pi-code-agent
You should see a pod named pi-code-agent (matching Sandbox.metadata.name).
4. Interact with Pi
Pi is a terminal TUI; attach to the running container:
POD_NAME="$(kubectl get pods -l sandbox=pi-code-agent -o jsonpath='{.items[0].metadata.name}')"
kubectl attach -it "${POD_NAME}"
Detach without killing Pi: press Ctrl+P, then Ctrl+Q.
Cleanup
kubectl delete -f sandbox.yaml
kubectl delete secret pi-code-agent-api-keys
The PVCs are retained by default. To delete them as well:
kubectl delete pvc -l sandbox=pi-code-agent
Configuration
- Different API provider: Pi supports multiple providers. Add additional env vars (e.g.,
OPENAI_API_KEY) tosandbox.yamland create corresponding entries in the Secret. - Different PVC sizes: edit
volumeClaimTemplatesinsandbox.yaml. - Tighter security: add a
securityContextto the container spec (seeexamples/nullclaw-sandbox/nullclaw-sandbox.yamlfor an example). - Newer Pi version: bump the version in
Dockerfile(@earendil-works/pi-coding-agent@<new-version>) and rebuild.