From dc1b1efbabfb1a35616f00df326c6d9c06c5230b Mon Sep 17 00:00:00 2001 From: Vadym Samoilenko Date: Mon, 23 Feb 2026 21:46:29 +0000 Subject: [PATCH] fix: use minimal Payload config in migrator to prevent OOM SIGKILL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- src/scripts/migrate.ts | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/scripts/migrate.ts b/src/scripts/migrate.ts index 228b622..b4611eb 100644 --- a/src/scripts/migrate.ts +++ b/src/scripts/migrate.ts @@ -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 });