Deploy
Host web and docs on Vercel, Nest API on Render with Neon Postgres.
Ship the Starter stack without Docker on the public internet:
| App | Platform | Notes |
|---|---|---|
apps/web | Vercel | Next.js, Bun monorepo install |
apps/docs | Vercel | Separate Vercel project |
apps/nest-api | Render | Docker Blueprint + Neon DATABASE_URL |
| Database | Neon | Serverless Postgres (TLS auto-detected) |
Repo files: apps/web/vercel.json, apps/docs/vercel.json, root render.yaml.
1) Neon database
- Create a project at console.neon.tech.
- Copy the pooled connection string (includes
sslmode=require). - You will paste it into Render as
DATABASE_URL. Nest enables TLS automatically forneon.techURLs.
2) Nest API on Render
- In Render, New → Blueprint and connect this GitHub repo (or create a Web Service with Docker).
- Use
render.yamlat the repo root (dockerfileapps/nest-api/Dockerfile, context.). - Fill sync: false env vars in the dashboard:
| Variable | Example |
|---|---|
DATABASE_URL | Neon pooled URL |
RESEND_API_KEY | re_... from Resend |
AUTH_EMAIL_FROM | Starter <noreply@your-domain.com> |
WEB_APP_URL | https://your-web.vercel.app (set after step 3) |
CORS_ORIGIN | same as WEB_APP_URL (comma-separate preview URLs if needed) |
WEBAUTHN_RP_ID | your-web.vercel.app (hostname only) |
WEBAUTHN_ORIGIN | https://your-web.vercel.app |
Blueprint already sets COOKIE_SAME_SITE=none, TRUST_PROXY=true, and generates JWT_SECRET, AUTH_TOKEN_SECRET, and AI_SERVICE_TOKEN.
- Deploy and confirm health:
curl -sS https://<your-service>.onrender.com/api/v1/healthMigrations run on container start when RUN_MIGRATIONS=true (default in the Blueprint).
Note: Free Render services spin down when idle; the first request can take ~30s. AI assist still needs a hosted apps/ai-api (AI_API_URL) later — Nest will boot without it.
3) Web on Vercel
- Add New Project → import the same repo.
- Root Directory:
apps/web. - Enable Bun (Project Settings → General → Package Manager, or rely on
vercel.jsoninstall). vercel.jsonalready sets install/build via Turbo (--filter=web).- Environment variables:
| Variable | Value |
|---|---|
NEXT_PUBLIC_NEST_API_URL | https://<your-service>.onrender.com (no /api path) |
NEXT_PUBLIC_GOOGLE_CLIENT_ID | optional; must match Nest GOOGLE_CLIENT_ID |
- Deploy. Then go back to Render and set
WEB_APP_URL/CORS_ORIGIN/ WebAuthn to this Vercel URL, and redeploy Nest if needed.
NEXT_PUBLIC_* is baked at build time — change the API URL → redeploy web.
4) Docs on Vercel
- Add another project from the same repo.
- Root Directory:
apps/docs. - Env (optional, for docs AI chat):
| Variable | Value |
|---|---|
OPENROUTER_API_KEY | from OpenRouter |
OPENROUTER_MODEL | e.g. anthropic/claude-3.5-sonnet |
- Deploy. Docs do not call Nest.
Cross-origin auth (important)
Web (*.vercel.app) and API (*.onrender.com) are different sites. Refresh cookies use:
COOKIE_SAME_SITE=noneSecure(HTTPS)
Local Docker stays on COOKIE_SAME_SITE=lax (default). Do not set COOKIE_DOMAIN across Vercel and Render hostnames — it cannot glue them.
Long-term option: put both under one parent domain (e.g. app.example.com + api.example.com) and tighten cookie settings.
Checklist
- Neon
DATABASE_URLon Render - Resend key + verified from-address
- Nest health returns OK
- Web
NEXT_PUBLIC_NEST_API_URL→ Render origin - Nest
CORS_ORIGIN/WEB_APP_URL→ Vercel web URL - Login works (cookie + credentials)
- Docs project live (optional OpenRouter)
Related
- Docker — local Compose stack
- Production roadmap — product phases
- Nest API README production notes under
apps/nest-api/