Skip to content

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 kadai task 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.

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.

bash
cd boilerhouse
bunx kadai run presets/claude-code   # or: presets/openclaw

When 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

bash
cd boilerhouse
bunx kadai run setup

This installs Go and TypeScript dependencies plus setup-envtest for controller tests.

2. Set Up a Local Cluster

bash
bunx kadai run minikube

This creates a minikube profile, installs the four Boilerhouse CRDs, and creates the boilerhouse namespace.

Verify the CRDs are installed:

bash
kubectl get crds | grep boilerhouse
boilerhouseclaims.boilerhouse.dev
boilerhousepools.boilerhouse.dev
boilerhousetriggers.boilerhouse.dev
boilerhouseworkloads.boilerhouse.dev

3. Start the Operator and API

bash
bunx kadai run dev

This 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:

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:

bash
kubectl apply -f workloads/minimal.yaml

5. Wait for the Workload to be Ready

The operator transitions the workload through Creating to Ready:

bash
kubectl get boilerhouseworkloads -n boilerhouse
NAME      PHASE   VERSION   IMAGE   AGE
minimal   Ready   0.1.0             30s

6. Claim an Instance

Claim a container for a tenant via the REST API:

bash
curl -X POST http://localhost:3000/api/v1/tenants/alice/claim \
  -H "Content-Type: application/json" \
  -d '{"workload": "minimal"}'
json
{
  "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:

bash
kubectl get boilerhouseclaims -n boilerhouse
kubectl get pods -n boilerhouse -l boilerhouse.dev/managed=true

7. Interact with the Instance

Run a command inside the container:

bash
curl -X POST http://localhost:3000/api/v1/instances/<instanceId>/exec \
  -H "Content-Type: application/json" \
  -d '{"command": ["echo", "hello from boilerhouse"]}'
json
{
  "exitCode": 0,
  "stdout": "hello from boilerhouse",
  "stderr": ""
}

View container logs:

bash
curl http://localhost:3000/api/v1/instances/<instanceId>/logs

8. 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.

bash
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:

yaml
# workloads/minimal-pool.yaml
apiVersion: boilerhouse.dev/v1alpha1
kind: BoilerhousePool
metadata:
  name: minimal-pool
  namespace: boilerhouse
spec:
  workloadRef: minimal
  size: 3
  maxFillConcurrency: 2
bash
kubectl apply -f workloads/minimal-pool.yaml

The operator pre-warms 3 Pods. Claims now return in under a second from the pool:

json
{
  "source": "pool"
}

Tear Down

Clean-slate teardown of the boilerhouse namespace — all Boilerhouse CRs, managed pods, services, PVCs, network policies, deployments, secrets, and configmaps:

bash
bunx kadai run nuke

After this, a preset will re-prompt for tokens and the allowlist on its next run.

Next Steps