Deployment

Next.js on Cloudflare Workers

The production path is a Next.js App Router build through OpenNext, a Cloudflare Worker with static assets, a D1 binding and an Email binding. The repository includes the configuration; a deploy still needs your own vars, secrets and verification.

Checked 2026-10-22

Architecture

VibeShip is a Next.js App Router application. OpenNext turns the server build into a Cloudflare Worker; static assets are served from the Worker's assets binding. D1 stores accounts, subscriptions, credits and the other product state that used to be shown in a browser-only demo.

The Worker also has an Email sending binding for sign-in codes and contact flows when that module is configured. The custom domain and routes live in `wrangler.jsonc`. Observability is enabled, which is useful when a request fails after the build looked healthy.

Build and deploy

Install with `npm ci`, run `npm run doctor` to see which configuration is present, apply D1 migrations, then build with `npm run cf:build` and deploy the Worker. The repository's CI workflow shows the same order and injects the production variables and secrets.

A deploy uploads a Worker version; it does not prove the customer journey. Verify sign-in, a test billing flow, the D1-backed pages and the AI endpoint on the deployed domain. A preview build and a live build are different modes; do not use a preview success as proof that production secrets are wired.

  • `npm ci` — install the locked dependency set.
  • `npm run doctor` — configuration presence, without printing secrets.
  • D1 migrations — additive schema changes before the new version serves.
  • `npm run cf:build` — OpenNext bundle for Workers.
  • Deploy — Worker, assets, D1, Email and routes.
  • Verify — public pages and provider-backed paths on the real domain.

Variables and secrets

`wrangler.jsonc` binds the Worker name, the OpenNext entry, assets, the D1 database, routes and the Email binding. Keep the plain variables and secrets that the application needs in the production environment: `DATABASE_DRIVER=d1`, the auth provider, the public site URLs, and, when enabled, Stripe, NextAuth and AI provider values.

A direct deploy that only lists `DATABASE_DRIVER` can drop the other production plain variables. Read the existing Worker settings before a manual deploy and pass the complete plain-variable set; secrets persist across a Worker deploy, but losing a plain variable can still break a route. The [getting-started guide](/docs/getting-started) and [launch verification](/docs/launch-verification) cover the configuration and the checks.

Limits

The Worker runtime is not a full Node.js server. Use the configured compatibility flags and the existing server adapters; do not assume a package that needs an unrestricted filesystem will work. D1 migrations are additive and should be applied before the new version serves.

Cloudflare configuration is not a promise that a third-party provider is reachable. Stripe, the AI provider and email each need their own verification. The template is a starting point with an explicit deployment path, not a claim that every clone is production-ready.

Preview versus production

Preview mode is for looking at the interface, not for proving a customer journey. It rejects writes and does not charge; live mode is the only place where D1, Stripe, email and the AI provider are exercised together. A preview page returning 200 is not evidence that a production secret is present.

Keep the two modes explicit in your own deployment: a preview build for review, then a live build with the production variables and secrets. Verify the live domain after the deploy, not just the local build.

Deployment checklist and failure modes

Before deploying, check the Worker name and route, the D1 database id, the assets and Email bindings, the plain variables and the secrets. Apply pending migrations, then build and deploy. Preserve the plain variables with the deploy command; a deploy that only carries DATABASE_DRIVER can make a working build look broken.

If a page fails after deploy, check the Worker logs and the provider status before changing the page code. A missing D1 binding, an unapplied migration, a stale OAuth callback or a provider key is a configuration failure; the build cannot prove those are correct.

Frequently asked questions

No. The wired production path is Cloudflare Workers through OpenNext, with D1 and the assets and Email bindings. Another host is an implementation decision; the repository's deploy configuration is Cloudflare-first.

Start from the template guide

The docs cover the full setup sequence: database, auth, billing, AI credits and the Cloudflare deployment.

Related guides