Makes schema changes deploy automatically: edit schema -> db:generate -> commit -> push -> Dokploy redeploys -> migrations apply on container start. No more Dokploy database terminal. Components: - src/db/migrate.ts: standalone migrator (single short-lived connection, fails loud on error so a bad migration crashes the container instead of letting the app serve a half-migrated schema) - scripts/build-migrator.mjs: esbuild bundles migrate.ts -> dist/migrate.mjs with drizzle-orm + postgres inlined. Needed because Next.js standalone output keeps neither as a separate node_modules package. - Dockerfile: builder runs db:build-migrator; runner copies migrate.mjs + drizzle/; CMD is 'node migrate.mjs && node server.js' - package.json: db:generate / db:migrate / db:studio / db:pull / db:build-migrator scripts; esbuild promoted to an explicit devDependency - pnpm-lock.yaml resynced BUG FIX: .dockerignore had 'drizzle/' — migration SQL was excluded from the build context, so even a correct Dockerfile COPY would have found nothing. This was the second half (with the .gitignore bug in commit 1) of why the migration pipeline never worked. Now only _archived/_introspected are excluded. Verified: full docker build succeeds; runner image contains migrate.mjs + drizzle baseline; migrator tested end-to-end against a scratch DB (35 tables created, __drizzle_migrations populated, idempotent on rerun).
30 lines
1.1 KiB
JavaScript
30 lines
1.1 KiB
JavaScript
/**
|
|
* Bundles src/db/migrate.ts into a single self-contained dist/migrate.mjs.
|
|
*
|
|
* Why: the Next.js standalone production image does NOT keep drizzle-orm or
|
|
* postgres as separate node_modules packages (Next traces them straight into
|
|
* server.js). The migration runner is a separate entrypoint, so it needs its
|
|
* own bundle with those deps inlined. esbuild does exactly that.
|
|
*
|
|
* esbuild is already available as a transitive dependency of drizzle-kit/tsx,
|
|
* so this adds no new package to the project.
|
|
*
|
|
* Run via: pnpm db:build-migrator (invoked automatically inside the build).
|
|
*/
|
|
import { build } from "esbuild";
|
|
|
|
await build({
|
|
entryPoints: ["src/db/migrate.ts"],
|
|
bundle: true, // inline drizzle-orm + postgres into the output
|
|
platform: "node",
|
|
target: "node22",
|
|
format: "esm",
|
|
outfile: "dist/migrate.mjs",
|
|
// postgres ships optional native bits; keep it bundled but let node resolve
|
|
// built-ins normally. No externals — we want a fully standalone file.
|
|
banner: {
|
|
js: "// AUTO-GENERATED by scripts/build-migrator.mjs — do not edit.",
|
|
},
|
|
});
|
|
|
|
console.log("[build-migrator] dist/migrate.mjs written.");
|