Crumb is AGPL-3.0 and runs entirely on your own infrastructure. The whole stack, dashboard plus widget plus Postgres, comes up from one file.
docker compose up -d --build # the dashboard listens on http://localhost:3000
Create the first admin
A fresh install has no users yet, so you create the first workspace and its admin at /onboard. That page opens with a one-time setup link you mint on the host. First set CRUMB_APP_URL to the address people will reach Crumb at, since the link is built from it:
docker compose exec dashboard node packages/db/dist/cli.mjs setup-link # prints a one-time https://your-crumb-host/onboard?token=... link, valid for 60 minutes
Open it, name your workspace, and you're signed in. After that, sign-in is by magic link, and customers hear back by email, so point Crumb at your SMTP relay (CRUMB_EMAIL_PROVIDER=smtp plus SMTP_HOST and SMTP_PORT). Until you do, emails only print to the dashboard's logs.
Prefer the full dev setup?
pnpm install pnpm db:up # Postgres in Docker pnpm db:push # apply the schema pnpm db:seed # sample data (the Southbeam workspace) pnpm widget:build # build the embed widget cp apps/dashboard/.env.local.example apps/dashboard/.env.local pnpm dev # http://localhost:3000
With the sample data loaded, sign in at /login as [email protected]; the magic link prints in your terminal.
Health checks
GET /api/health for liveness and GET /api/health/ready (200 only when the database is reachable). Handy behind a load balancer.
Keep it tidy
A few cron jobs keep things fresh: a sweep for orphaned uploads, a CRM refresh if you connected one, and a pull for any feedback connectors. Set CRUMB_INTERNAL_SWEEP_SECRET first; the endpoints refuse to run without it.
# nightly: sweep orphaned uploads curl -X POST -H "X-Crumb-Sweep-Secret: $CRUMB_INTERNAL_SWEEP_SECRET" \ http://localhost:3000/api/v1/internal/replay-sweep # every few hours: refresh CRM accounts + ARR curl -X POST -H "X-Crumb-Sweep-Secret: $CRUMB_INTERNAL_SWEEP_SECRET" \ http://localhost:3000/api/v1/internal/crm-sync # every 20 minutes or so: pull from Zendesk, Intercom, Gong, and friends curl -X POST -H "X-Crumb-Sweep-Secret: $CRUMB_INTERNAL_SWEEP_SECRET" \ http://localhost:3000/api/v1/internal/feedback-sync
Back it up
docker compose exec -T postgres \ pg_dump -U crumb -Fc crumb > crumb-$(date +%F).dump