From df7ddbfb0d37b170953209a4f68e45141def40da Mon Sep 17 00:00:00 2001 From: DJP Date: Mon, 20 Apr 2026 21:33:55 -0400 Subject: [PATCH] Dockerfile: install tsx globally so it stops disappearing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `npm install --no-save tsx` in the runner stage was reporting success but the tsx binary kept vanishing from node_modules/.bin after the Next.js standalone node_modules reshuffled its tree. The seed then failed with "sh: tsx: not found" even after a clean rebuild. Install tsx globally instead (npm install -g tsx@4 → /usr/local/bin/tsx), which is PATH-resolvable regardless of any local node_modules churn. Other seed-adjacent deps stay local (prisma CLI, dotenv, adapter-pg, bcryptjs) because the seed script explicitly imports them and wants them resolved from the app's local node_modules. Co-Authored-By: Claude Opus 4.7 (1M context) --- Dockerfile | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2ba17c2..1a68ca6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -44,18 +44,26 @@ COPY --from=builder /app/src/generated ./src/generated # Install runtime deps needed for migrations + seed. The Next.js standalone # bundle covers the app itself, but the seed script (prisma/seed-dow.ts) is -# a separate .ts file executed via tsx and needs its own module graph: +# a separate .ts file executed via tsx. +# +# tsx is installed GLOBALLY (lives at /usr/local/bin/tsx, on PATH +# unconditionally). Installing it locally via `npm install --no-save tsx` +# doesn't work reliably here because Next.js's standalone node_modules +# layout aggressively reshuffles its own tree — the tsx binary was +# repeatedly going missing from node_modules/.bin after what npm reported +# as a successful install. Global install sidesteps that entirely. +# +# Other deps are local (alongside the standalone tree): # prisma — the migrate-deploy CLI # dotenv — prisma.config.ts imports dotenv/config -# tsx — runs the seed without an ahead-of-time compile # @prisma/adapter-pg — the driver the seed instantiates directly # bcryptjs — the seed hashes the admin's temp password -RUN npm install --no-save \ - prisma@7.4.2 \ - dotenv@17.3.1 \ - tsx@4 \ - @prisma/adapter-pg@7.4.2 \ - bcryptjs@3 +RUN npm install -g tsx@4 && \ + npm install --no-save \ + prisma@7.4.2 \ + dotenv@17.3.1 \ + @prisma/adapter-pg@7.4.2 \ + bcryptjs@3 # Create uploads directories for media storage RUN mkdir -p /data/uploads && chown nextjs:nodejs /data/uploads