# Domains, updates and deployment recovery

URL: https://ship-and-scale.vercel.app/docs/operations/deployment

Maintain the deployed app, preserve its provider identities and understand the limits of rollback.

## Start from the initial deployment [#start-from-the-initial-deployment]

Use [Deployment Kickstart](/docs/start/deployment-kickstart) for the first repository, project and runtime installation. This guide begins after that workflow has recorded its GitHub repository, Vercel project and source commit. Keep the original setup folder and its private receipts, even if day-to-day development moves to a clone.

The initial production branch is `main`, installation uses `npm ci`, and Vercel builds with `npm run build`. Verify those settings before diagnosing a different branch or output as a failed production release.

## Assigned and custom domains [#assigned-and-custom-domains]

Kickstart obtains an actual production `vercel.app` domain from the designated Vercel project. It checks verification and routing before using it for shared Auth/MCP configuration. Do not guess an available alias from the project name.

For an initial custom domain, set the intended HTTPS origin in `APP_URL_LIVE`, then follow **Vercel Project → Settings → Domains**. Add the exact DNS records Vercel displays at the authoritative DNS provider. A domain purchase, ownership check and registrar edit remain your responsibility. Use the provider-supplied records rather than a copied IP address from an unrelated tutorial. See [Vercel domain setup](https://vercel.com/docs/domains/working-with-domains/add-a-domain).

Wait until the domain is verified, correctly routes to production and serves HTTPS. Then rerun the paused deployment command. The source refuses redirects, branch-specific domain bindings and uncertain routing at this step. It preserves the prior shared origin until the check passes.

A domain change **after activation** is deliberately guarded. The installer reports that the live origin changed and stops; it does not ship a generic post-launch domain migration/reconciliation command. Do not change the value and delete its receipt to trick it into being a first run. Plan the cutover, confirm the exact provider target, and update the relevant callbacks/audience/runtime state with reviewed steps while keeping a recovery record.

## Active and saved origins [#active-and-saved-origins]

| Value/state                    | Meaning                                                             |
| ------------------------------ | ------------------------------------------------------------------- |
| Local `.env` `APP_URL`         | Active origin for that local app process                            |
| `APP_URL_DEV`                  | Saved development reference                                         |
| `APP_URL_LIVE`                 | Saved/verified production reference                                 |
| Hosted Auth/email/MCP settings | One currently configured origin shared by local and deployed source |
| Vercel runtime `APP_URL`       | Verified live origin supplied to production                         |

Development and production share hosted Supabase/Auth/email state. Stripe alone uses distinct test/live resources. Deployment transitions hosted callbacks, email links and the MCP audience to production while the local `.env` can retain its local `APP_URL`. An older local page is not proof that hosted callbacks still target localhost.

To intentionally restore the local configuration, set local `APP_URL` to the desired local origin and run:

```sh
npm run kickstart -- --restore-local
```

Use this only when you intend to affect production's shared Auth/email/MCP behavior. Arrange the operational impact first. It is not a harmless local preview switch or a Vercel code rollback. Existing OAuth clients may need to reconnect after either origin transition.

## Disabled previews [#disabled-previews]

The supported project disables automatic preview deployments. Arbitrary per-branch URLs cannot safely share the single configured Auth/MCP origin. If you need independent staging, design a separate authorized hosted project, provider modes/senders and state, with explicit isolation and costs. Enabling preview builds alone does not establish that setup.

Public pages may be inspectable in a separate static build, but do not use them to claim staging authentication, email or subscription isolation. Keep staging indexing disabled regardless.

## Updates after the first snapshot [#updates-after-the-first-snapshot]

After bootstrap, clone the private repository returned by the installer. That repository contains a clean application snapshot, not the original folder's Git history. Use normal branches/review and push tested changes to `main` for Vercel's configured Git deployment. The installer refuses unrecorded remote commits and changed source after linking Vercel, preserving your later work.

For an ordinary text/UI change, inspect your diff, run the relevant checks, commit in your application clone and push through your normal workflow. Keep secrets and setup receipts out of that commit. Confirm Vercel builds the expected commit and the changed page serves correctly.

For a future starter release, compare its changes with your customized copy. There is no automatic update mechanism in this release, and Git cannot reliably merge independent snapshot histories as if they shared every ancestor. Apply reviewed changes or a deliberate patch; resolve conflicts, account for renamed/customized files, run the affected tests, and read migration instructions. Retain a record of the starter version/source snapshot your product began with.

## Runtime and database changes [#runtime-and-database-changes]

An environment change affects the next relevant build/deployment according to its use. Public build-time values require a rebuild; server values still need the intended deployment configuration. Use `scripts/kickstart/deploy-config.mjs` as the exact runtime allowlist reference. Never bulk-copy local `.env` into Vercel.

## Add a custom server secret [#add-a-custom-server-secret]

For a server-only integration that is not in Kickstart's runtime allowlist, open the exact Vercel project saved in the deployment receipt and choose **Settings -> Environment Variables**. Add only that integration's unprefixed key, mark it sensitive where available and select **Production**. Keep the value on the server; never use a `NEXT_PUBLIC_` name or return it to a browser. Save, then create a new Production deployment from the reviewed commit so the new deployment receives the value. Existing deployments do not inherit later variable changes.

If local server code also needs the key, add it individually to the local `.env`. Do not upload the whole setup `.env`, and do not put Supabase Management, GitHub or Vercel setup tokens in Vercel. An Edge Function needs its own specifically selected Supabase secret and redeployment.

Migrations are separately versioned persistent changes. Keep released files immutable, prepare a new migration and use the established Management API/checksum runner with the correct origin and target. Do not casually rerun an old installer against an application repository that has advanced; the guard may require explicit reconciliation. Preserve database compatibility while rolling out code that depends on a new column or policy.

## Code rollback and provider state [#code-rollback-and-provider-state]

A Vercel rollback changes deployed application code. It does not undo SQL, Stripe products/prices/subscriptions, sent email, deleted files or Auth configuration. Before rolling back, confirm the older code can read the current schema and billing state. Prefer additive schema changes and forward corrections over assumptions that a code revert restores the world.

If a build fails, keep the failed deployment for diagnosis. Fix the source in Git and deploy normally. If HTTPS checks fail, inspect DNS, routing and deployment protection; the installer does not automatically weaken protection. A ten-minute waiting limit can expire while the same deployment is still building—rerun to resume waiting on its saved ID.

## Recovery and evidence [#recovery-and-evidence]

Retain `.kickstart/deploy-<project-ref>.json`, matching Supabase/Stripe receipts and `.secrets` privately. They record identities and operation progress needed to avoid duplicate resources. After a crash, remove only a proven stale `install.lock`; never clear uncertain-operation markers or delete all setup state.

Your release evidence should identify the deployed commit, domain, runtime origin, callback test, invitation/recovery inbox receipt, MCP audience test and payment lifecycle result. Record a subsequent Git change reaching production and a rehearsed recovery on a safe target. This manual's local build does not establish custom-domain routing, a subsequent deployment or provider rollback acceptance; those are target-specific checks.