fix: run DB migrations via migrator service, not standalone app

In Next.js standalone output (output: 'standalone') the src/migrations/
directory is not present on the filesystem, so payload.db.migrate()
could not discover migration files → home_page table was never created
→ getHomePage() threw a DB error → Server Components render failed.

Fix:
- Add `migrator` service to docker-compose.prod.yml (builds from the
  `migrator` Dockerfile stage which has the full src/ tree)
- migrator runs `pnpm payload migrate` before app starts
- app depends_on migrator: service_completed_successfully
- Remove payload.db.migrate() from instrumentation.ts (migrator handles it)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Vadym Samoilenko 2026-02-23 21:31:52 +00:00
parent 3f6dfe36b1
commit 96ab1c5da6
2 changed files with 21 additions and 10 deletions

View file

@ -1,4 +1,19 @@
services:
# Run pending Payload migrations before the app starts.
# Uses the `migrator` image stage (has full src/) so TS files are discoverable.
migrator:
build:
context: .
target: migrator
restart: "no"
networks:
- internal
env_file:
- .env.production
depends_on:
db:
condition: service_healthy
app:
build:
context: .
@ -20,6 +35,8 @@ services:
depends_on:
db:
condition: service_healthy
migrator:
condition: service_completed_successfully
db:
image: postgres:17-alpine

View file

@ -1,17 +1,11 @@
// Runs on Next.js startup (Node.js runtime only) before any requests are handled.
// Uses compiled/bundled code — no tsx/ESM resolution issues.
// Migrations are handled by the `migrator` Docker service (docker-compose.prod.yml)
// which runs before this container starts, so no migration call is needed here.
export async function register() {
if (process.env.NEXT_RUNTIME === 'nodejs') {
const { getPayload } = await import('payload');
const { default: config } = await import('@payload-config');
const payload = await getPayload({ config });
// In dev mode Payload auto-pushes schema changes — migrations only needed in production
if (process.env.NODE_ENV === 'production') {
console.log('[startup] Running database migrations...');
await payload.db.migrate();
console.log('[startup] Migrations complete.');
}
// Initialize Payload (connects to DB, registers collections/globals)
await getPayload({ config });
}
}