Ship with deploy config
Generate Vercel, Cloudflare, Fly or Docker files from main.yaml, run schedules on a serverless platform, fail the build on a missing secret and review a staging to production change.
Status Status is where the work is: Planned (in a milestone, not started), Building (tickets in progress), Preview (usable, may change), then the stability it ships at.
Stability The promise an interface ships with.
- Stable Follows semantic versioning; breaking changes need a new major, 12 months of overlap and a codemod.
- Beta Usable in production; may change before it becomes stable.
- Experimental May change or go away; needs an explicit opt-in in main.yaml.
You will generate the platform's deploy files from main.yaml, wake a schedule through the tick route, and review what a promotion to production changes. It takes about 20 minutes. MainSDK writes and checks the files; the platform's Git integration or CLI still deploys.
You need
- A MainSDK app with a
main.yamland a production overlaymain.env.prod.yaml(see Deploy on Vercel). - The app's data regions declared in
db.regions.
1. Pick a target and a schedule
Set the target in the production overlay and declare the schedule in main.yaml:
deploy:
target: vercel
vercel: { plan: pro }jobs:
schedules:
nightly-report: "0 3 * * *"2. Write the files
npx mainsdk deploy config --env prodThis writes vercel.json (regions, one cron for nightly-report, a build command that runs the preflight), deploy/env.prod.example and mainsdk.deploy.json. Commit all three. Keys you added to vercel.json yourself are not touched. Run it again after any change to main.yaml; mainsdk deploy config --check and mainsdk check fail when a generated block is stale.
3. Serve the tick route
On vercel and cloudflare the platform's cron calls one route. Mount it before your own routes and set CRON_SECRET in the platform:
import { app } from "mainsdk";
import { createTick } from "mainsdk/deploy";
const tick = createTick(app());
export const POST = (req: Request) => tick.handle(req);On Cloudflare Workers export scheduled: (event) => tick.scheduled(event) next to fetch, and the same job is queued in process with no HTTP call.
4. Let the build refuse a missing secret
The generated build command runs mainsdk deploy preflight --env prod first. Try it with a name unset:
CRON_SECRET=x npx mainsdk deploy preflight --env prodIt exits 1 with MAIN-DEPLOY-0003 and lists the missing names, never a value.
5. Review the promotion
npx mainsdk deploy diff --from staging --to prod --fail-on widenIt lists changed config, env names, schedules, regions and grants, and exits 1 with MAIN-DEPLOY-0012 for each change that lets production do more than staging.
Check it worked
Run npx mainsdk check --env prod. It passes when the generated files match main.yaml, the regions sit inside the data regions and the schedules fit the plan.
Was this page helpful?