const { runner } = require('node-pg-migrate'); const { Client } = require('pg'); const path = require('path'); const direction = process.argv[2] || 'up'; const dbConfig = { host: process.env.PGHOST || 'localhost', port: parseInt(process.env.PGPORT || '5432', 10), user: process.env.PGUSER, password: process.env.PGPASSWORD, database: process.env.PGDATABASE }; // This now runs at container start, ahead of the app, so it can come up before // Postgres is accepting connections — on the NAS the database container is // routinely slower to be ready than the app container. Without a wait the // migration would fail, take the app down with it, and look like a broken // deploy rather than a startup race. const WAIT_ATTEMPTS = 30; const WAIT_INTERVAL_MS = 2000; async function waitForDb() { for (let attempt = 1; attempt <= WAIT_ATTEMPTS; attempt++) { const client = new Client(dbConfig); try { await client.connect(); await client.end(); return; } catch (err) { await client.end().catch(() => {}); if (attempt === WAIT_ATTEMPTS) { throw new Error(`Database unreachable after ${WAIT_ATTEMPTS} attempts: ${err.message}`); } console.log(`Waiting for database (attempt ${attempt}/${WAIT_ATTEMPTS})...`); await new Promise((resolve) => setTimeout(resolve, WAIT_INTERVAL_MS)); } } } waitForDb() .then(() => runner({ databaseUrl: dbConfig, dir: path.resolve(__dirname, 'migrations'), direction, migrationsTable: 'pgmigrations', count: direction === 'down' ? 1 : Infinity, log: (msg) => console.log(msg) }) ) .then((applied) => { console.log(`Migration complete — ${applied.length} migration(s) ${direction === 'down' ? 'reverted' : 'applied'}.`); process.exit(0); }) .catch((err) => { console.error('Migration failed:', err.message); process.exit(1); });