Skip to content

Run it locally

Docker Compose v2
Go 1.22+
Node 20+
MongoDB on :27017, or let the bundled container start it

Everything runs from the cavs-node/ package of the monorepo, not from the repository root:

Terminal window
cd cavs-node
cp .env.example .env # optional — run.sh does it for you
./run.sh # infra + api + worker + web
URL What
http://localhost:5173 Dashboard
http://localhost:8080/healthz API health
http://localhost:8080/readyz API readiness (pings MongoDB)
http://localhost:9001 MinIO console — cavsminio / cavsminio123

Sub-commands:

Terminal window
./run.sh infra # Docker services only
./run.sh services # api + worker + web only
./run.sh down # stop infra
./run.sh logs # tail api and worker
./run.sh all # everything (foregrounds the web dev server)

run.sh uses your local MongoDB if one is listening on :27017, otherwise it starts the bundled container. On boot the API creates indexes and seeds the plan catalogue — both idempotent.

Service Port Notes
MongoDB 27017 Local or bundled
MinIO 9000 / 9001 S3-compatible object store; bucket cavs-cloud-dev
Pub/Sub emulator 8085 No credentials needed
Redis 6379 Optional cache
cavs-api 8080
cavs-worker Health server on $PORT
cavs-web (Vite) 5173 Proxies /api to :8080

The dashboard uses real Firebase Authentication — there is no mock. Put your project’s config in web/src/firebase-config.ts (or set the VITE_FIREBASE_* variables) and set FIREBASE_PROJECT_ID so the API verifies ID tokens against the same project.

Terminal window
FIREBASE_PROJECT_ID=your-firebase-project
AUTH_DEV_BYPASS=false

AUTH_DEV_BYPASS=true accepts unsigned tokens so you can poke the API with curl. It is backend-only (the web app always uses real Firebase) and forced off when CAVS_ENV=production.

The stack is designed to still run with pieces missing:

Missing Effect
Pub/Sub emulator The API falls back to a no-op bus — events aren’t delivered, everything else works
Redis Nothing; the cache is optional
MinIO / S3 Uploads and downloads fail; the control plane works
MongoDB Nothing works — it’s the source of truth

You still need MongoDB and, for real transfers, an S3 endpoint.

These are the ones that actually cost time.

Without disturbing MongoDB, MinIO, Redis or Pub/Sub:

Terminal window
pkill -f '\.run/cavs-api'
pkill -f '\.run/cavs-worker'
set -a && . ./.env && set +a
nohup .run/cavs-api > .run/api.log 2>&1 &
nohup .run/cavs-worker > .run/worker.log 2>&1 &
disown -a

The original ./run.sh all stays alive but its tracked PIDs are now stale. A clean re-run also rebuilds the Go binaries and resets the environment.

Terminal window
cav config set api http://localhost:8080
cav login

For a plaintext-HTTP remote the transfer agent refuses to upload unless you opt in:

Terminal window
export CAVS_LFS_ALLOW_INSECURE_HTTP=1
Terminal window
cd services && go test ./...

Store integration tests are gated on MONGO_TEST_URI — a local MongoDB on :27017 works:

Terminal window
MONGO_TEST_URI=mongodb://localhost:27017 go test ./internal/store/...

Dashboard end-to-end tests use Playwright:

Terminal window
cd web && npx playwright test