Deploy

Ship your stage, and later, production.

Your first deploy

bun run deploy

Deploys to your personal dev stage (SST uses your system username as the stage name by default).

Before touching Cloudflare, bun run deploy runs a preflight check (scripts/doctor.ts — also available alone as bun run doctor). It stops the deploy, with the exact fix, when something known to break it is wrong:

  • the @nuxfire/* workspace links are missing (bun install wasn't run in this folder);
  • CLOUDFLARE_API_TOKEN / CLOUDFLARE_ACCOUNT_ID aren't set in your shell, or the token is invalid, expired or belongs to another account;
  • the stage's secrets file (.env.stage, or .env.production for production) has empty DATABASE_* values;
  • the Branding in that same file (BRAND_NAME, BRAND_DOMAIN, BRAND_EMAIL) is missing or malformed — the same validation the deploy itself runs.

What it can't prove — for example, your domain not showing up in the account — is printed as a warning (!) and doesn't stop the deploy. To check the production secrets file instead, run bun run doctor -- --stage production.

Prompt for AI agents:

Run bun run deploy. It runs a preflight check first — if that reports a
problem, fix what it says before retrying. If the deploy itself fails,
check the error against AGENTS.md's
Infra / SST gotchas and Database sections before proposing a fix —
several documented failures (Supabase pooler/direct mismatch, missing
workers.dev subdomain, unenv version conflicts) read like a different
problem than they actually are.

What happens automatically

apps/functions/src/database/seed/index.ts runs on every deploy, right after migrations, and creates the Free plan plus the system roles/permissions — idempotent, so running it again never duplicates anything. Paid plans are deliberately left out (Stripe/Paddle price IDs are per environment) — they're created at /admin/plans by the platform owner.

The platform-owner account and MFA-gated /admin console are a separate, deliberate manual step — see Platform Admin Console.

Deploying to other stages

  • Development: uses your system username as the stage name by default — this is what bun run deploy does with no flags.
  • Production: fill in .env.production with real production values (including its own Branding section), load it, and deploy:
    bunx sst secret load .env.production --stage production
    bun run deploy -- --stage production
    
  • Custom stages: bun run deploy -- --stage custom-name (the -- is required to pass the flag through the bun run wrapper).

Prompt for AI agents:

For production: confirm .env.production is filled with real production
values (never copy .env.stage's values into it), then run
bunx sst secret load .env.production --stage production (no --fallback)
followed by bun run deploy -- --stage production. If the user needs a
platform-owner account, that's a separate step — see the Platform Admin
Console doc, and never seed a known owner password on a real environment.

Next

Local Development — run the app day to day.

Nuxfire Production Kit

Ready to build and launch your SaaS?

Get 100% full source code ownership, zero proprietary wrappers, and architecture engineered for millions of requests on Cloudflare.

© 2026 Nuxfire