fix: use minimal Payload config in migrator to prevent OOM SIGKILL

The migrator was importing the full payload.config.ts which loads lexical
editor + form-builder plugin — very heavy modules that caused the process
to be SIGKILL'd (exit 9) on the VPS.

The new migrate.ts builds an inline minimal config: only the postgres
adapter + explicit migrationDir. No editor, no plugins, no
collections/globals needed to run raw SQL migrations. This should fit
comfortably within VPS memory limits.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Vadym Samoilenko 2026-02-23 21:46:29 +00:00
parent 1ba1349607
commit dc1b1efbab

View file

@ -1,12 +1,31 @@
/**
* Production migration runner.
* Run via: NODE_OPTIONS="--experimental-strip-types --no-require-module" node src/scripts/migrate.ts
* Lightweight production migration runner.
*
* Uses the same Node.js native TS-stripping approach as seed.ts.
* Called by the `migrator` Docker service before the app starts.
* Uses a minimal inline Payload config no lexical editor, no plugins, no
* collections/globals to avoid loading heavy modules in a memory-constrained
* environment (the full config would OOM a small VPS via SIGKILL).
*
* Run via: NODE_OPTIONS="--experimental-strip-types --no-require-module" node src/scripts/migrate.ts
*/
import { getPayload } from 'payload';
import config from '../payload.config.ts';
import path from 'path';
import { fileURLToPath } from 'url';
import { buildConfig, getPayload } from 'payload';
import { postgresAdapter } from '@payloadcms/db-postgres';
const filename = fileURLToPath(import.meta.url);
const dirname = path.dirname(filename);
// Minimal config: only the DB adapter + explicit migrations path.
// No editor, no plugins, no collections/globals needed to run raw SQL migrations.
const config = buildConfig({
secret: process.env.PAYLOAD_SECRET || 'migrate-secret',
db: postgresAdapter({
pool: { connectionString: process.env.DATABASE_URI },
migrationDir: path.resolve(dirname, '../migrations'),
}),
collections: [],
globals: [],
});
const payload = await getPayload({ config });