Skip to content
mango·agentby Mangosteen Studio

What gets deployed where#

Mango Agent has four parts. The backend (FastAPI API, WebSockets and the background worker in one process) and the panel (Next.js inbox and admin) run together on a server. The widget (mango.js) and this website are static files that belong on a CDN such as Cloudflare. The backend needs Postgres with pgvector, Redis and an S3-compatible bucket for screenshots.

Pick a setup to see where each part runs and roughly what it costs.

The backend has to stay running: it holds WebSocket connections open, and its worker delivers push notifications, unclaimed-handoff fallbacks and weekly reports. The worker is safe on several instances, because jobs are claimed with SKIP LOCKED and the hourly job takes a Redis lock.

Choose a setup#

SetupRough monthly costServer workGood for
Free GCP VM (e2-micro) + Docker Compose$0–4You run updates and backupsInternal use on a budget; push works with no key file
Any VM: DigitalOcean, Hetzner, Lightsail…$6–12You run updates and backupsSame, on a provider you already use
Railway$5–10Almost noneLeast maintenance, deploys on every push
Cloud Run (managed GCP)$45+NoneAutoscaling for real traffic
Costs are estimates from public price lists, for low internal traffic. Check each provider's pricing page. Gemini usage is billed separately; cap it per project with daily_token_budget.

Measured footprint of the production stack: backend about 185 MB of RAM, panel 95 MB, Postgres 40 MB, Caddy 60 MB, Redis 4 MB. A 1 GB server is enough for internal use.

Push notifications need a Google identity#

Phone push goes through Firebase Cloud Messaging, which needs a Google service account. On GCP (a VM or Cloud Run), attach the service account to the machine and set PUSH_PROVIDER=fcm: nothing to store, nothing expires. Elsewhere, paste a service-account key into GOOGLE_CREDENTIALS_JSON (base64). If your Google organization forbids key files, that's a reason to prefer GCP.

Shared setup (any option)#

  • Domains: api.<domain> for the backend and app.<domain> for the panel, plus optional names for the widget and website.
  • Firebase: enable Google and Email/Password sign-in, and add app.<domain> under Authentication → Settings → Authorized domains.
  • Screenshot bucket: a Cloudflare R2 bucket (free up to 10 GB) and an API token with Object Read & Write. The backend only creates buckets in development, so create it yourself.
  • Backups bucket: a second R2 bucket, mango-backups, with its own token scoped to it. The nightly database dump is uploaded there.
  • Redis: the bundled container, or a hosted one like Upstash's free tier. Mango sends about 4–5 commands a minute while idle, plus about 15 per chat message.
  • Secrets: SECRET_KEY (openssl rand -base64 48), a Gemini API key, APP_ENV=production and AUTH_MODE=firebase. Every value is in deploy/env.production.example.
  • CORS: CORS_ALLOW_ORIGINS must list the panel and every site that embeds the widget, as exact origins.

Widget and website on Cloudflare#

mango-agent repo: widget
npx wrangler@4 login                # once
deploy/cloudflare/deploy-widget.sh  # build, check the 40 KB budget, deploy
website repo
pnpm deploy:cloudflare   # static export to out/ and wrangler deploy

Both are served as static assets from Cloudflare's CDN. The widget files are cached for 5 minutes, so updates reach every site quickly. With a custom domain, the embed tag becomes:

html
<script src="https://cdn.<domain>/mango.js" data-project="pk_…" data-api="https://api.<domain>" async></script>

After the first deploy#

  • Load a seed with your email as owner. Sign-in is invite-only, so the first owner comes from a seed file.
  • Sign in at https://app.<domain> with Google, or with First time? Set a password.
  • Add the team under Members, giving each person project access, and add projects. Copy each project's embed tag from its Embed card.
  • Press Send test in the inbox header to check push.