Deploying the hosted service
One Docker image runs everything: the API, the built web app, the public site, the bots' browsers and the per-organisation sandbox. Data (SQLite database, vault, per-organisation workspaces, browser profiles) lives on one persistent volume.
Fly.io (reference setup)
fly launch --copy-config --no-deployin the repo (usesfly.toml: regionfra, oneperformance-2xmachine, volumebb_data).fly volumes create bb_data --size 20 --region fra- Secrets — generate the vault key once and never lose it (every stored API key and connector token is encrypted with it):
fly secrets set BB_VAULT_KEY=$(openssl rand -base64 32) BB_ADMIN_EMAILS=you@company.com STRIPE_SECRET_KEY=sk_live_… STRIPE_WEBHOOK_SECRET=whsec_… STRIPE_PRICE_PRO=price_… STRIPE_PRICE_TEAM=price_… STRIPE_PRICE_SEAT=price_… RESEND_API_KEY=re_… EMAIL_FROM="BuddyBots <hello@buddybots.app>" COMPOSIO_API_KEY=ak_… OPENROUTER_API_KEY=sk-or-…
fly deploy, thenfly certs add app.buddybots.appand point the DNS at it. SetBB_PUBLIC_URLinfly.tomlto the same address: invite links, OAuth callbacks and Chrome pairing codes are built from it.- Stripe: create the three prices (Pro monthly, Team monthly, extra seat monthly), add a webhook endpoint
https://app.buddybots.app/api/billing/webhookforcheckout.session.completed,customer.subscription.created,customer.subscription.updated,customer.subscription.deleted,invoice.paid,invoice.payment_failed, and enable the customer portal. - Composio: one platform key serves every organisation (each connects its own accounts; the Composio user id is
buddybots-<workspace id>). Set the OAuth callback allowlist tohttps://app.buddybots.app/api/composio/callback. - Resend: verify the sending domain, then
EMAIL_FROMmust use it.
Checks after deploy
GET /api/status→{ ok: true, version, sandbox: "bwrap", multi: true }.sandbox: "restricted"means bubblewrap could not start (usually the container runtime forbids user namespaces): run with--cap-add SYS_ADMINor on a runtime that allows unprivileged user namespaces, otherwise every organisation's shell commands share one host user./,/pricing,/docs/,/terms,/privacy,/statusrender;/appshows the sign-in card.- Sign up, invite a second address, check both emails arrive.
- Buy Pro with a Stripe test card; the Usage screen switches plan within a second of the webhook.
Backups
The volume holds everything. fly volumes snapshots list bb_data (daily snapshots are automatic on Fly); for off-site copies run tar czf - /data | … from a fly ssh console. The vault key is a secret, not on the volume — keep it in your password manager.
Scaling
Vertical first (fly scale vm performance-4x --memory 8gb). SQLite with WAL handles thousands of organisations of this shape; move to Postgres when write contention shows in /api/status latency or when you need more than one machine writing. Browser profiles and workspaces are files: put them on object storage before going multi-machine.
Self-hosted
npm run setup && npm run dev — no accounts, no billing, everything on your own computer. docker compose up -d with BB_TOKEN for a single-owner server; add BB_MULTI=1 and BB_PUBLIC_URL to turn that same container into a hosted instance.