Search code examples
node.jsnext.jspnpm

Standalone Next.js server returns 404 for static content unless next start is called at least once


I'm trying to deploy the following project to production: https://github.com/saleor/apps The submodule in question: https://github.com/saleor/apps/tree/main/apps/slack

Here are the steps I'm taking.

  • cd /apps/slack
  • pnpm install
  • pmpm build (this runs graphql-codegen && next build)

I have set output: "standalone" in my next.config.js

The problem is when I try to run the standalone server using:

node .next/standalone/apps/slack/server.js

I get 404s: 404s in chrome inspector

Until I do:

  • pnpm start (runs next start)
  • Open a browser and go to localhost:3000
  • Kill pnpm start

Then the 404s go away... even when running node .next/standalone/apps/slack/server.js enter image description here

I'm asking because this seems to be related to Next.js not to the app itself? But I'm not experienced with Next.js or Node development so I'm not sure.

This is a problem for me because I want to make a docker image. And I'm having issues translating this workflow into a Dockerfile.

Edit:

I tried using the Dockerfile from https://github.com/vercel/next.js/tree/canary/examples/with-docker However they don't include start in the build process.

Edit 2:

By running diff -qr working/ broken/ I found no differences after running pnpm start. Can this be caused by Chrome caching?

Edit 3:

It appears to be a caching issue, as after running pnpm start and accessing the page from chrome the issue persists in Firefox when using the standalone server.js However I have no idea why the page loads when using next start and not node server.js

Thanks.


Solution

  • In a pnpm monorepo, when using Next.js standalone output you have to manually copy the static and public folders.

    Additionally, a minimal server.js file is also output which can be used instead of next start. This minimal server does not copy the public or .next/static folders by default as these should ideally be handled by a CDN instead, although these folders can be copied to the standalone/public and standalone/.next/static folders manually, after which server.js file will serve these automatically.

    However I was copying them to the wrong destination, causing the 404s.

    Copy to standalone/apps/slack/.next instead of standalone/.next, same thing for public.

    https://nextjs.org/docs/app/api-reference/next-config-js/output#automatically-copying-traced-files