Quick Start
This guide gets you from zero to a running multi-tenant container on a local minikube cluster. Supported on macOS and Linux.
Prerequisites
- Go 1.26+
- Docker and minikube
- Bun v1.3+ (for the
kadaitask runner) - The Boilerhouse repository cloned locally
Presets check every tool before running and print an OS-appropriate install hint if anything is missing, so you can safely skip ahead and fix things as they come up.
Option A — One-command demo (recommended)
The quickest path to a working demo uses a preset. A preset runs setup, bootstraps minikube, prompts for a Telegram bot token + Anthropic key + allowlist, applies a demo workload, and starts the dev loop.
cd boilerhouse
bunx kadai run presets/claude-code # or: presets/openclawWhen the "Ready to chat" banner appears, DM the bot from an allowlisted Telegram account.
Presets are intended for local demos only. Production deployments (in-cluster operator/API, ingress, etc.) are out of scope for this guide.
If you only want to try Boilerhouse end-to-end, skip to step 10 (Tear Down) when you're done. The steps below walk through the lower-level building blocks.
Option B — Step-by-step
1. Install Dependencies
cd boilerhouse
bunx kadai run setupThis installs Go and TypeScript dependencies plus setup-envtest for controller tests.
2. Set Up a Local Cluster
bunx kadai run minikubeThis creates a minikube profile, installs the four Boilerhouse CRDs, and creates the boilerhouse namespace.
Verify the CRDs are installed:
kubectl get crds | grep boilerhouseboilerhouseclaims.boilerhouse.dev
boilerhousepools.boilerhouse.dev
boilerhousetriggers.boilerhouse.dev
boilerhouseworkloads.boilerhouse.dev3. Start the Operator and API
bunx kadai run devThis runs the operator and API server locally against your minikube cluster. The API listens on http://localhost:3000. Ctrl+C stops both.
4. Apply a Workload
Boilerhouse ships with an example minimal workload in workloads/minimal.yaml:
apiVersion: boilerhouse.dev/v1alpha1
kind: BoilerhouseWorkload
metadata:
name: minimal
namespace: boilerhouse
spec:
version: "0.1.0"
image:
dockerfile: minimal/Dockerfile
resources:
vcpus: 1
memoryMb: 128
diskGb: 1
network:
access: "none"
idle:
timeoutSeconds: 300
action: hibernate
entrypoint:
cmd: sh
args: ["-c", "echo 'minimal container ready' && exec sleep infinity"]Apply it:
kubectl apply -f workloads/minimal.yaml5. Wait for the Workload to be Ready
The operator transitions the workload through Creating to Ready:
kubectl get boilerhouseworkloads -n boilerhouseNAME PHASE VERSION IMAGE AGE
minimal Ready 0.1.0 30s6. Claim an Instance
Claim a container for a tenant via the REST API:
curl -X POST http://localhost:3000/api/v1/tenants/alice/claim \
-H "Content-Type: application/json" \
-d '{"workload": "minimal"}'{
"tenantId": "alice",
"phase": "Active",
"instanceId": "inst-alice-minimal-a1b2c3",
"endpoint": { "host": "10.244.0.12", "port": 0 },
"source": "cold",
"claimedAt": "2026-04-20T10:30:00Z"
}The operator created a BoilerhouseClaim resource, which spawned a Pod. You can see both:
kubectl get boilerhouseclaims -n boilerhouse
kubectl get pods -n boilerhouse -l boilerhouse.dev/managed=true7. Interact with the Instance
Run a command inside the container:
curl -X POST http://localhost:3000/api/v1/instances/<instanceId>/exec \
-H "Content-Type: application/json" \
-d '{"command": ["echo", "hello from boilerhouse"]}'{
"exitCode": 0,
"stdout": "hello from boilerhouse",
"stderr": ""
}View container logs:
curl http://localhost:3000/api/v1/instances/<instanceId>/logs8. Release the Tenant
When the tenant is done, release their claim. If the workload has overlayDirs configured, the operator extracts and saves the tenant's filesystem state before shutting down the Pod.
curl -X POST http://localhost:3000/api/v1/tenants/alice/release \
-H "Content-Type: application/json" \
-d '{"workload": "minimal"}'Next time Alice claims the same workload, her filesystem state is restored automatically.
9. Enable Pooling
For faster claim times, apply a BoilerhousePool resource:
# workloads/minimal-pool.yaml
apiVersion: boilerhouse.dev/v1alpha1
kind: BoilerhousePool
metadata:
name: minimal-pool
namespace: boilerhouse
spec:
workloadRef: minimal
size: 3
maxFillConcurrency: 2kubectl apply -f workloads/minimal-pool.yamlThe operator pre-warms 3 Pods. Claims now return in under a second from the pool:
{
"source": "pool"
}Tear Down
Clean-slate teardown of the boilerhouse namespace — all Boilerhouse CRs, managed pods, services, PVCs, network policies, deployments, secrets, and configmaps:
bunx kadai run nukeAfter this, a preset will re-prompt for tokens and the allowlist on its next run.
Next Steps
- Workloads — image sources, resources, health checks, idle policies
- Tenants & Claims — multi-tenancy model, claim lifecycle
- Networking & Security — network access modes, credential injection
- Dashboard — inspect live cluster state in a browser