diff --git a/Dockerfile b/Dockerfile index c5bfa163..6fb18bec 100644 --- a/Dockerfile +++ b/Dockerfile @@ -49,6 +49,13 @@ RUN apk upgrade --no-cache && \ COPY --from=builder /app/public ./public COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static +# next/dist/lib/metadata/** (get-metadata-route.js and its neighbours). A +# plain top-level require in router-utils/filesystem.js, yet Next's own +# output file tracing for `output: "standalone"` + `next build --webpack` +# drops the whole directory - the server crashes on its first line with +# "Cannot find module '../../../lib/metadata/get-metadata-route'" without +# this. Same tracing-gap class as the plugins copy below. +COPY --from=builder --chown=nextjs:nodejs /app/node_modules/next/dist/lib/metadata ./node_modules/next/dist/lib/metadata # Staged first-party plugin bundles. Read by path at runtime, so Next's output # file tracing does not carry them into .next/standalone - copy explicitly or # the image boots with the S/MIME policy toggle on and no plugin installed. diff --git a/scripts/assemble-standalone.mjs b/scripts/assemble-standalone.mjs index adb05fb2..bc238dc3 100644 --- a/scripts/assemble-standalone.mjs +++ b/scripts/assemble-standalone.mjs @@ -81,4 +81,20 @@ if (existsSync(pluginsSrc)) { ); } +// next/dist/lib/metadata/** (get-metadata-route.js and its neighbours). +// +// router-utils/filesystem.js has a plain top-level `require("../../../lib/ +// metadata/get-metadata-route")` - not dynamic, not conditional - yet Next's +// own output-file-tracing for `output: "standalone"` + `next build --webpack` +// drops the entire directory. Verified by inspecting a real build: the +// package was present, this one subfolder was missing, so the standalone +// server crashed on its very first line with "Cannot find module" - every +// packaged build (Electron and Docker) was affected. Same failure class as +// the sqlcipher prebuilds above: copy by hand what the tracer misses. +const metadataSrc = path.join(rootDir, "node_modules", "next", "dist", "lib", "metadata"); +const metadataDest = path.join(standaloneDir, "node_modules", "next", "dist", "lib", "metadata"); +rmSync(metadataDest, { recursive: true, force: true }); +cpSync(metadataSrc, metadataDest, { recursive: true }); +console.log("Copied next/dist/lib/metadata into the standalone output"); + console.log("Assembled standalone server at", standaloneDir);