A platform for running interactive coding workshops with isolated learner workspaces powered by Firecracker MicroVMs.
# See all available commands
make help
# Start development (run in separate terminals)
make backend # Terminal 1: Start backend server (port 8080)
make frontend # Terminal 2: Start frontend dev server (port 5173)
# Run tests
make test # All Go tests
make test-e2e # E2E test against GCP (classic workspace)
make test-vscode # E2E test for VS Code workspace
# Deploy to Cloud Run
make deploy-all # Deploy backend + frontendclarateach/
├── frontend/ # React web application
├── backend/ # Go API server and agent
├── workspace/ # MicroVM workspace server (Node.js)
├── scripts/ # Build, setup, and test scripts
├── docs/ # Architecture and planning documentation
└── tests/ # Integration tests
| Component | Technology | Description |
|---|---|---|
| Frontend | React + Vite + TypeScript | Web UI for teachers and learners. Includes terminal (xterm.js), code editor (Monaco), and file browser. |
| Backend Server | Go (Chi router) | Control plane API. Manages workshops, provisions GCP VMs, orchestrates MicroVMs. Runs on port 8080. |
| Backend Agent | Go | Runs on worker VMs. Manages Firecracker MicroVMs, proxies terminal/file requests. Runs on port 9090. |
| Workspace Server | Node.js | Runs inside each MicroVM. Provides terminal (port 3001) and file API (port 3002) for learners. |
| Rootfs Builder | Go | Builds the ext4 root filesystem image used by MicroVMs. |
┌─────────────────────────────────────────────────────────────────┐
│ Frontend (React) │
│ - Teacher dashboard │
│ - Learner workspace (terminal + editor + files) │
└──────────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Backend Server (port 8080) │
│ - Workshop CRUD API │
│ - GCP VM provisioning │
│ - Agent coordination │
└──────────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ GCP Worker VM (clara2) │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ Agent (port 9090) │ │
│ │ - MicroVM lifecycle (create/destroy) │ │
│ │ - Proxy: terminal WebSocket, file API │ │
│ └───────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ MicroVM 1 │ │ MicroVM 2 │ │ MicroVM 3 │ ... │
│ │ (seat 1) │ │ (seat 2) │ │ (seat 3) │ │
│ │ .100.11 │ │ .100.12 │ │ .100.13 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────────┘
- Go 1.24+
- Node.js 20+
- Docker (for rootfs building)
- GCP access (for full E2E testing)
# Start backend and frontend (requires 2 terminals)
make backend # Terminal 1: Backend server (port 8080)
make frontend # Terminal 2: Frontend dev server (port 5173)
# Check if services are running
make status
# Build backend binaries
make build # Creates backend/server and backend/agent-linux# Run all Go tests
make test
# Run unit tests only (no integration tests)
make test-unit
# E2E tests against GCP Cloud Run
make test-e2e # Classic workspace type
make test-vscode # VS Code workspace type# Build lightweight test rootfs (~50MB, 5 seconds)
make rootfs-test
# Build classic rootfs (~2GB)
make rootfs-classic
# Build VS Code rootfs (~3GB)
make rootfs-vscodeNote: Rootfs builds must run on Linux (GCP VM), not macOS.
# Deploy to Cloud Run (uses snapshot from .snapshot file)
make deploy-all # Deploy backend + frontend
make deploy-backend # Backend only
make deploy-frontend # Frontend only
# Override snapshot for a single deployment
make deploy-all SNAPSHOT=clara2-snapshot-20260121
# Tail backend logs
make logs-backend# Check current snapshot
make set-snapshot
# Set a new snapshot for deployments
make set-snapshot NAME=clara2-snapshot-20260121
# Update agent on running VM and create new snapshot
make snapshot-update
# Prepare VM for snapshot (run ON the VM)
make snapshotRun make help for the full list. Key targets:
| Target | Purpose |
|---|---|
make backend |
Start backend server locally |
make frontend |
Start frontend dev server |
make status |
Check if services are running |
make build |
Build backend binaries |
make test |
Run all Go tests |
make test-e2e |
Run E2E tests (classic workspace) |
make test-vscode |
Run E2E tests (VS Code workspace) |
make deploy-all |
Deploy backend + frontend to Cloud Run |
make deploy-backend |
Deploy backend only |
make deploy-frontend |
Deploy frontend only |
make set-snapshot |
Show/set snapshot for deployments |
make snapshot-update |
Update agent and create new snapshot |
make logs-backend |
Tail Cloud Run backend logs |
| Script | Purpose | Makefile Target |
|---|---|---|
deploy-cloud-run.sh |
Deploy to GCP Cloud Run | make deploy-* |
build-rootfs.sh |
Build classic rootfs (~2GB) | make rootfs-classic |
build-vscode-rootfs.sh |
Build VS Code rootfs (~3GB) | make rootfs-vscode |
build-test-rootfs.sh |
Build lightweight test rootfs | make rootfs-test |
test-e2e-gcp.sh |
E2E tests against Cloud Run | make test-e2e |
start-backend.sh |
Start backend server | make backend |
start-frontend.sh |
Start frontend server | make frontend |
prepare-snapshot.sh |
Prepare VM for GCP snapshot | make snapshot |
update-agent-snapshot.sh |
Update agent on running VM | make snapshot-update |
| Variable | Description | Default |
|---|---|---|
PORT |
Server port | 8080 |
GCP_PROJECT |
GCP project ID | clarateach |
GCP_ZONE |
GCP zone | us-central1-b |
GCP_REGISTRY |
Artifact Registry URL | - |
FC_SNAPSHOT_NAME |
Snapshot name for worker VMs | From .snapshot file |
BACKEND_URL |
Public URL for VM tunnel registration | Auto-set by deploy script |
CORS_ORIGINS |
Allowed CORS origins | * |
JWT_SECRET |
Secret for JWT signing | Secret Manager |
DATABASE_URL |
PostgreSQL connection string | Secret Manager |
| Variable | Description | Default |
|---|---|---|
AGENT_PORT |
Agent port | 9090 |
WORKER_ID |
Worker identifier | hostname |
IMAGES_PATH |
Path to kernel and rootfs | /var/lib/clarateach/images |
BACKEND_URL |
Backend URL for tunnel registration | - |
| File | Purpose |
|---|---|
.snapshot |
Stores current snapshot name for deployments |
- TestingGuide.md - How to test MicroVM functionality
- CurrentFeature.md - Current development focus
- ARCHITECTURE.md - System architecture
- API_SPEC.md - API specification
- CLOUD_RUN_DEPLOYMENT.md - Deployment guide
# See all available commands
make help
# Check backend health (local)
curl localhost:8080/health
# Check backend health (Cloud Run)
curl https://clarateach-backend-864969804676.us-central1.run.app/health
# Check agent health (on VM)
curl localhost:9090/health
# List MicroVMs
curl localhost:9090/vms
# Create a MicroVM
curl -X POST localhost:9090/vms -H "Content-Type: application/json" \
-d '{"workshop_id": "test", "seat_id": 1}'
# Delete a MicroVM
curl -X DELETE localhost:9090/vms/test/1-
Commit code first (required for version tracking):
git add -A && git commit -m "description"
-
Deploy to Cloud Run:
make deploy-all
-
Verify deployment:
curl -s https://clarateach-backend-864969804676.us-central1.run.app/health | jq .
-
If updating VM agent, create new snapshot:
make snapshot-update make set-snapshot NAME=<new-snapshot-name> make deploy-backend
Cause: BACKEND_URL not set, VMs can't register tunnel
Fix: make deploy-backend and recreate the workshop
Cause: VM creation failed or agent didn't start Check: GCP Console → Compute Engine → workshop VM logs
Cause: Tunnel not registered (same as above) Verify:
curl https://clarateach-backend-864969804676.us-central1.run.app/api/session/{access-code}
# Should show "endpoint": "https://xxx.trycloudflare.com"