Prisma's generated client calls fileURLToPath(import.meta.url) to locate its query engine binary. In CJS output that's undefined, and the require of the seed bundle blew up before running a line of actual seed code. ESM output (.mjs) runs natively on Node 22, import.meta.url resolves correctly, everything else about the bundle (external npm packages, inlined generated client) stays the same. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
106 lines
3.6 KiB
Docker
106 lines
3.6 KiB
Docker
FROM node:22-alpine AS base
|
|
|
|
# FFmpeg for video transcoding (HLS), thumbnail extraction, and metadata
|
|
RUN apk add --no-cache ffmpeg
|
|
|
|
# Install dependencies only when needed
|
|
FROM base AS deps
|
|
WORKDIR /app
|
|
COPY package.json package-lock.json* ./
|
|
RUN npm ci --ignore-scripts
|
|
RUN npx prisma generate || true
|
|
|
|
# Rebuild source code only when needed
|
|
FROM base AS builder
|
|
WORKDIR /app
|
|
COPY --from=deps /app/node_modules ./node_modules
|
|
COPY . .
|
|
|
|
# Generate Prisma client
|
|
RUN npx prisma generate
|
|
|
|
# Build the Next.js app
|
|
RUN npm run build
|
|
|
|
# Pre-compile the seed to a self-contained ESM bundle. Runtime then runs
|
|
# plain `node prisma/seed-dow.mjs` and avoids the whole tsx+module-
|
|
# resolution nightmare: Next.js's standalone node_modules was aggressively
|
|
# reshuffling the tree after install, leaving packages like postgres-array
|
|
# with a manifest but no index.js. Bundling sidesteps that entirely.
|
|
#
|
|
# ESM (not CJS) because Prisma's generated client uses `import.meta.url`
|
|
# for engine detection — that's `undefined` in CJS and crashes on load.
|
|
#
|
|
# `--packages=external` keeps NPM packages (bcryptjs, @prisma/*) as
|
|
# runtime import() calls so the bundle stays small and native .node files
|
|
# in @prisma/client work normally.
|
|
RUN npx -y esbuild@0.24 prisma/seed-dow.ts \
|
|
--bundle --platform=node --format=esm --target=node22 \
|
|
--outfile=prisma/seed-dow.mjs \
|
|
--packages=external
|
|
|
|
# Production image
|
|
FROM base AS runner
|
|
WORKDIR /app
|
|
|
|
ENV NODE_ENV=production
|
|
|
|
RUN addgroup --system --gid 1001 nodejs
|
|
RUN adduser --system --uid 1001 nextjs
|
|
|
|
COPY --from=builder /app/public ./public
|
|
|
|
# Copy Next.js standalone output
|
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
|
|
|
# Copy Prisma schema, config, and migrations for runtime
|
|
COPY --from=builder /app/prisma ./prisma
|
|
COPY --from=builder /app/prisma.config.ts ./prisma.config.ts
|
|
COPY --from=builder /app/src/generated ./src/generated
|
|
|
|
# Runtime deps — the Next.js standalone bundle covers the app itself;
|
|
# Runtime deps. The Next.js standalone tree ships with PARTIAL copies of
|
|
# the pg driver chain — package.json manifests present but index.js
|
|
# missing. npm's "version already satisfies, skipping" logic then fires
|
|
# on every subsequent install attempt (including --force), because the
|
|
# manifest version check passes and npm never looks at file integrity.
|
|
#
|
|
# Nuke the whole pg chain explicitly before reinstalling. Fail-fast at
|
|
# the end so if it ever silently regresses we see FATAL in the build
|
|
# log, not four hours later at seed time.
|
|
RUN rm -rf \
|
|
node_modules/@prisma/adapter-pg \
|
|
node_modules/pg \
|
|
node_modules/pg-cloudflare \
|
|
node_modules/pg-connection-string \
|
|
node_modules/pg-int8 \
|
|
node_modules/pg-numeric \
|
|
node_modules/pg-pool \
|
|
node_modules/pg-protocol \
|
|
node_modules/pg-types \
|
|
node_modules/postgres-array \
|
|
node_modules/postgres-bytea \
|
|
node_modules/postgres-date \
|
|
node_modules/postgres-interval \
|
|
&& npm install --no-save \
|
|
prisma@7.4.2 \
|
|
dotenv@17.3.1 \
|
|
@prisma/adapter-pg@7.4.2 \
|
|
pg@8 \
|
|
bcryptjs@3 \
|
|
&& test -f node_modules/postgres-array/index.js \
|
|
|| (echo "FATAL: postgres-array/index.js still missing after reinstall" >&2 && exit 1)
|
|
|
|
# Create uploads directories for media storage
|
|
RUN mkdir -p /data/uploads && chown nextjs:nodejs /data/uploads
|
|
RUN mkdir -p /app/public/uploads/revisions && chown -R nextjs:nodejs /app/public/uploads
|
|
|
|
USER nextjs
|
|
|
|
EXPOSE 3000
|
|
|
|
ENV PORT=3000
|
|
ENV HOSTNAME="0.0.0.0"
|
|
|
|
CMD ["sh", "-c", "./node_modules/.bin/prisma migrate deploy && node server.js"]
|