Three pieces to host: Postgres, the two FastAPI services, and the React app. Free tiers everywhere. ~20 minutes end to end.
Pick one shared
WEBHOOK_SECRET(any long random string) and use the same value on both backend services.
- Create a free Postgres at https://neon.tech → copy the connection string.
(The CRM auto-rewrites
postgres://→postgresql+asyncpg://, so paste it as-is.)
Easiest path uses the included render.yaml blueprint:
- Push this repo to GitHub.
- Render → New → Blueprint → pick the repo. It creates
reach-crm+reach-channel(the database is external on Neon — paste its URL intoDATABASE_URLbelow). - Set env vars when prompted:
- Both services:
WEBHOOK_SECRET= your shared secret. - reach-crm:
DATABASE_URL(Neon string, or auto-wired if using Render's DB), and an LLM provider + key:LLM_PROVIDER=groq+GROQ_API_KEY(free at https://console.groq.com/keys), orLLM_PROVIDER=gemini+GEMINI_API_KEY. - reach-crm also:
SEED_ON_STARTUP=true(auto-seeds demo data on first boot; idempotent, so it skips on later restarts). This avoids needing to reach the DB from your own machine.
- Both services:
- After both are live, set on reach-crm and redeploy:
CHANNEL_SERVICE_URL = https://reach-channel.onrender.comCRM_PUBLIC_URL = https://reach-crm.onrender.com
- Data is seeded automatically via
SEED_ON_STARTUP. (Alternatively, unset it and runpython -m app.seedfrom Render → reach-crm → Shell.)
Render free web services sleep when idle; the first request after a nap takes ~30s to wake. Hit the CRM URL once before demoing.
- Vercel → New Project → import the repo → set Root Directory to
web. - Env var:
VITE_API_BASE = https://reach-crm.onrender.com. - Deploy. (Framework preset: Vite. Build
npm run build, outputdist.) - Add the Vercel URL to the CRM's
CORS_ORIGINS(or leave*for the demo) and redeploy CRM.
- Open the Vercel URL → AI Copilot → "win back lapsed lipstick buyers" → Approve & Launch.
- Watch the campaign funnel fill. If callbacks don't arrive, re-check that
CRM_PUBLIC_URLis the CRM's public URL andWEBHOOK_SECRETmatches on both services.
Fill the live URLs into the top of README.md when done.