Files
website/docs/deployment-runbook.md
T
2026-04-28 09:16:15 +08:00

3.8 KiB

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.

For the command-level Chinese handoff guide, see docs/local-db-to-production-deployment.md.

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. Run local release checks: npm run lint, npm run typecheck, npm run build, and npm run payload:migrate:status.
  2. Load the local release environment with set -a; source .env; set +a, then confirm the local release database has no dev marker: psql "$DATABASE_URI" -Atc "select count(*) from payload_migrations where batch = -1;".
  3. Export the approved PostgreSQL database: pg_dump --format=custom --no-owner --no-acl --file=eversolo.payload.dump "$DATABASE_URI".
  4. Export matching uploads: tar -czf eversolo.uploads.tgz media files.
  5. Restore the approved PostgreSQL dump into the production database with pg_restore --no-owner --no-acl.
  6. Copy media/ and files/ to the production persistent upload volume.
  7. Install dependencies with npm ci.
  8. Run npm run generate:types only during build validation, not as a production data mutation step.
  9. Run npm run typecheck.
  10. Run npm run build.
  11. Run npm run payload:migrate.
  12. Run npm run payload:migrate:status and confirm every migration is Yes.
  13. Start the app with npm run start.
  14. Run npm run smoke -- "$NEXT_PUBLIC_SITE_URL".
  15. Log out of the admin, open /admin/login, and confirm the verification code is required before password validation.

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.
  • Admin login captcha is stateless and signed with PAYLOAD_SECRET; changing that secret invalidates existing login sessions and outstanding captcha tokens.

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.