Harden production deployment workflow
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
# Deployment Runbook
|
||||
|
||||
This runbook is the source of truth for taking the Eversolo Payload/Next.js site from a local database and media folder to a production deployment.
|
||||
|
||||
## Release Inputs
|
||||
|
||||
- Git commit to deploy.
|
||||
- PostgreSQL database dump exported from the approved local database.
|
||||
- `media/` and `files/` directories exported from the same local workspace as the database dump.
|
||||
- Production environment variables from `.env.example`, filled with production values.
|
||||
|
||||
## Required Environment
|
||||
|
||||
Use Node.js 22 LTS or newer. The project declares `>=20.9.0`, but production should use one pinned LTS line.
|
||||
|
||||
Required variables:
|
||||
|
||||
- `NEXT_PUBLIC_SITE_URL`: public canonical origin, for example `https://www.eversolo.com`.
|
||||
- `PAYLOAD_SECRET`: long random secret, never use the example value.
|
||||
- `DATABASE_URI`: PostgreSQL connection string.
|
||||
- `PAYLOAD_DB_PUSH=false`: production must use migrations, not schema push.
|
||||
- `PAYLOAD_RUN_MIGRATIONS_ON_START=false`: production startup should not run migrations interactively.
|
||||
|
||||
Optional variables:
|
||||
|
||||
- `PORT`: runtime port for `next start`.
|
||||
- `SMOKE_BASE_URL`: base URL used by `npm run smoke`.
|
||||
|
||||
## Deployment Steps
|
||||
|
||||
1. Restore the approved PostgreSQL dump into the production database.
|
||||
2. Copy `media/` and `files/` to the production persistent upload volume.
|
||||
3. Install dependencies with `npm ci`.
|
||||
4. Run `npm run generate:types` only during build validation, not as a production data mutation step.
|
||||
5. Run `npm run typecheck`.
|
||||
6. Run `npm run build`.
|
||||
7. Run `npm run payload:migrate`.
|
||||
8. Run `npm run payload:migrate:status` and confirm every migration is `Yes`.
|
||||
9. Start the app with `npm run start`.
|
||||
10. Run `npm run smoke -- "$NEXT_PUBLIC_SITE_URL"`.
|
||||
|
||||
## Data Rules
|
||||
|
||||
- Do not run `PAYLOAD_DB_PUSH=true` against production.
|
||||
- Do not rely on application startup to run migrations. Use the explicit migration step.
|
||||
- Before exporting a local database for production, confirm `payload_migrations` has no `batch = -1` dev marker. That marker means schema push history is still recorded and production migration commands can prompt interactively.
|
||||
- Do not edit migrations after they have shipped to production. Add a new forward migration instead.
|
||||
- Keep schema migrations and data backfills separate. Backfill scripts in `src/scripts/` are manual operational tools, not automatic boot steps.
|
||||
- The deployed database and upload directories must come from the same local export, otherwise media relationships can point at missing files.
|
||||
|
||||
## Rollback
|
||||
|
||||
Rollback means switching code and data together:
|
||||
|
||||
1. Stop traffic or move traffic back to the previous deployment.
|
||||
2. Restore the previous database dump.
|
||||
3. Restore the matching previous `media/` and `files/` directories.
|
||||
4. Deploy the previous Git commit.
|
||||
5. Re-run smoke checks before reopening traffic.
|
||||
|
||||
Do not run migration down scripts on production as the default rollback path.
|
||||
@@ -23,3 +23,13 @@ This project is being tightened toward launch as a CMS-first Eversolo brand site
|
||||
- Prefer compact admin groups, list-style arrays, and explicit per-locale documents for user-facing content.
|
||||
- Re-run `npm run generate:types`, `npm run build`, and the smoke check after schema or cache changes.
|
||||
- After restarting a local preview, check both `/en` and `/zh` for homepage, product detail, downloads, news, dealers, support, and admin access.
|
||||
|
||||
## Deployment Discipline
|
||||
|
||||
- Production uses migrations only. `PAYLOAD_DB_PUSH` must be `false`.
|
||||
- Production startup does not auto-run migrations by default. Run `npm run payload:migrate` as an explicit release step.
|
||||
- The local release database must not contain Payload's `dev` migration marker (`batch = -1`) before it is exported.
|
||||
- Local database exports must be paired with the same `media/` and `files/` directories.
|
||||
- Backfill scripts are manual release tools. They should be run before export, verified, and then treated as data already present in the production dump.
|
||||
- Production startup should fail fast if required secrets are missing instead of booting with development defaults.
|
||||
- `/api/health` should return `200` before traffic is switched to the deployment.
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
# Production Release Checklist
|
||||
|
||||
Use this checklist before every production deployment.
|
||||
|
||||
## Code
|
||||
|
||||
- [ ] Working tree is clean.
|
||||
- [ ] Latest commit is the intended release commit.
|
||||
- [ ] `npm ci` succeeds from a clean install.
|
||||
- [ ] `npm run typecheck` passes.
|
||||
- [ ] `npm run build` passes.
|
||||
- [ ] `npm run payload:migrate:status` shows all migrations as `Yes` on the release database.
|
||||
- [ ] `payload_migrations` has no `batch = -1` dev marker before exporting/importing the database.
|
||||
- [ ] No new user-facing fallback copy was introduced without a CMS field.
|
||||
|
||||
## Environment
|
||||
|
||||
- [ ] `NEXT_PUBLIC_SITE_URL` is the final public domain.
|
||||
- [ ] `PAYLOAD_SECRET` is set and is not `change-me` or the example value.
|
||||
- [ ] `DATABASE_URI` points to the production PostgreSQL database.
|
||||
- [ ] `PAYLOAD_DB_PUSH=false` is set.
|
||||
- [ ] `PAYLOAD_RUN_MIGRATIONS_ON_START=false` is set unless a one-off controlled migration boot is intentionally planned.
|
||||
- [ ] Upload directories `media/` and `files/` are persistent and backed up.
|
||||
|
||||
## CMS Data
|
||||
|
||||
- [ ] English and Chinese homepage content render.
|
||||
- [ ] Product list and at least one product detail page render in both locales.
|
||||
- [ ] Downloads list and one download detail page render.
|
||||
- [ ] News list and one news detail page render.
|
||||
- [ ] Reviews page tabs render, with local media covers where present.
|
||||
- [ ] Support page and video tutorials render, with local media covers.
|
||||
- [ ] Dealers page map visibility matches CMS setting.
|
||||
|
||||
## Smoke Routes
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
npm run smoke -- "$NEXT_PUBLIC_SITE_URL"
|
||||
```
|
||||
|
||||
Required manual spot checks:
|
||||
|
||||
- `/en`
|
||||
- `/zh`
|
||||
- `/en/products/dmp-a10`
|
||||
- `/en/reviews?tab=reviews`
|
||||
- `/en/support`
|
||||
- `/en/support/tutorial`
|
||||
- `/admin`
|
||||
- `/api/health`
|
||||
|
||||
## Launch Notes
|
||||
|
||||
- Keep old production database and upload volume snapshots until the new release has passed smoke checks and editorial QA.
|
||||
- If schema push or migration prompts appear during app startup, stop. Production startup should not be running schema push or migrations.
|
||||
- If media thumbnails are missing, verify the upload volume before changing CMS records.
|
||||
Reference in New Issue
Block a user