Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

All static assets (js/css/media) in Standalone mode become 404 #49283

Closed
1 task done
OZZlE opened this issue May 5, 2023 · 32 comments
Closed
1 task done

All static assets (js/css/media) in Standalone mode become 404 #49283

OZZlE opened this issue May 5, 2023 · 32 comments
Labels
bug Issue was opened via the bug report template. locked Output (export/standalone) Related to the the output option in `next.config.js`.

Comments

@OZZlE
Copy link

OZZlE commented May 5, 2023

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
      Platform: win32
      Arch: x64
      Version: Windows 10 Enterprise
    Binaries:
      Node: 18.12.1
      npm: N/A
      Yarn: N/A
      pnpm: N/A
    Relevant packages:
      next: 13.4.1-canary.1
      eslint-config-next: 13.2.4
      react: 18.2.0
      react-dom: 18.2.0

Which area(s) of Next.js are affected? (leave empty if unsure)

Standalone mode (output: "standalone")

Link to the code that reproduces this issue

asdf

To Reproduce

next.config.js

const { i18n } = require('./next-i18next.config')

/** @type {import('next').NextConfig} */
const nextConfig = {
  // assetPrefix: ".", // https://github.com/vercel/next.js/issues/8158#issuecomment-687707467
  output: 'standalone', // https://developers.redhat.com/articles/2022/11/23/how-deploy-nextjs-applications-red-hat-openshift#building_a_container_to_run_your_next_js_application
  reactStrictMode: true,
  productionBrowserSourceMaps: true,
  i18n,
  async redirects() {
    return [
      {
        source: '/da-en/:slug*',
        destination: '/en/:slug*',
        permanent: true,
      },
      {
        source: '/fi-en/:slug*',
        destination: '/en/:slug*',
        permanent: true,
      },
      {
        source: '/fi-sv/:slug*',
        destination: '/sv/:slug*',
        permanent: true,
      },
      {
        source: '/no-en/:slug*',
        destination: '/en/:slug*',
        permanent: true,
      },
      {
        source: '/sv-en/:slug*',
        destination: '/en/:slug*',
        permanent: true,
      },
    ]
  },
}

module.exports = nextConfig

Run: npm run build

Run: node .next/standalone/server.js

Open http://localhost:3000

Describe the Bug

All js and css files become 404

p://localhost:3000/_next/static/css/36abb935a2bfb1bb.css net::ERR_ABORTED 404 (Not Found)
p://localhost:3000/favicon.ico 404 (Not Found)
p://localhost:3000/_next/static/chunks/main-764a718264343ae9.js net::ERR_ABORTED 404 (Not Found)
etc

Expected Behavior

It can find and load all js/css files

Which browser are you using? (if relevant)

Latest Chrome

How are you deploying your application? (if relevant)

IISNode

@OZZlE OZZlE added the bug Issue was opened via the bug report template. label May 5, 2023
@github-actions github-actions bot added the Output (export/standalone) Related to the the output option in `next.config.js`. label May 5, 2023
@yarinsa
Copy link

yarinsa commented May 7, 2023

I am having the exact same issue

@kane50613
Copy link

same issue here

@OZZlE OZZlE changed the title All static assets (js/css) in Standalone mode become 404 All static assets (js/css/media) in Standalone mode become 404 May 8, 2023
@magentaqin
Copy link

next version "12.2.3" same issue here.

@labs-scnm
Copy link

Any solutions or idea about this? I have the same issue on v13.3.0.

@OZZlE
Copy link
Author

OZZlE commented May 12, 2023

Any solutions or idea about this? I have the same issue on v13.3.0.

I used this instead works much better.. https://nextjs.org/docs/pages/building-your-application/configuring/custom-server

not sure what Standalone mode is meant for

@ducan-ne
Copy link

I faced this issue today, I just found a workaround for this: copy .next/static to .next/standalone/.next/static

@vnglst
Copy link

vnglst commented May 20, 2023

Looking at the docs it seems that this is intended behavior:

“ 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.”

https://nextjs.org/docs/pages/api-reference/next-config-js/output

@klarstrup
Copy link

Yeah this is intended behavior as per the documentation for the standalone output mode.

@benweiser
Copy link

Confusingly, it seems you need to write your own script copy these assets over to the build folder yourself. An opt-in that would allow the Next build to do this for you would be nice if a CDN wasn't configured to serve these assets

@mohamed--abdel-maksoud
Copy link

Sharing the script I had to write to make this work (next version 13, output directory is called dist):

  "scripts": {
    "deploy": "next build && mkdir -p dist/standalone/public/_next && cp -r dist/static dist/standalone/public/_next/"
  },

@luis-herazo
Copy link

luis-herazo commented Aug 22, 2023

The script that works

"scripts": {
    "deploy": "next build && cp -r .next/static .next/standalone/.next/ && cp -r public .next/standalone/"
}

go to standalone folder
then when run: node server.js

@renenadorp
Copy link

Having the same issue. Using next 13.0.6.

@felipemullen
Copy link

felipemullen commented Oct 9, 2023

As far as I can tell, this is not a code issue, but maybe a documentation issue. If you look at the example dockerfile that uses standalone, it shows how the files are copied.

I shortened it into a working docker example for myself. (note that dumb-init is not strictly necessary):

FROM node:18-alpine AS build

RUN apk add --no-cache libc6-compat

WORKDIR /app
COPY package.json .
RUN npm install --omit=dev
COPY . .
RUN npm run build

# Image for running the app
FROM node:18-alpine
RUN apk update && apk upgrade
RUN apk add --no-cache dumb-init
WORKDIR /app

# These are the important file copies
COPY --from=build /app/public ./public
COPY --from=build /app/.next/standalone ./
COPY --from=build /app/.next/static ./.next/static

EXPOSE 8080
ENV HOST=0.0.0.0 NODE_ENV=production PORT=8080
CMD ["dumb-init", "node", "server.js"]

@terwer
Copy link

terwer commented Oct 18, 2023

感谢非常有用

@sladg
Copy link

sladg commented Nov 17, 2023

I faced this issue today, I just found a workaround for this: copy .next/static to .next/standalone/.next/static

Can confirm, works with Next 13 for me.

@jannisbecker
Copy link

jannisbecker commented Dec 14, 2023

Copying the assets manually works, yeah.

I just don't think everyone will want to host them on CDNs. Could we perhaps get a config option that controls whether or not these assets are copied to the standalone folder?

@paolomainardi
Copy link

paolomainardi commented Jan 9, 2024

I am facing the same issue here, tried with 14.0.3 and 14.0.4 using a docker container and standalone mode.

Dockerfile:

FROM node:18-alpine

ENV NODE_ENV production

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

WORKDIR /app
RUN mkdir .next
RUN chown nextjs:nodejs /app

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --chown=nextjs:nodejs public ./public
COPY --chown=nextjs:nodejs dist/standalone ./
COPY --chown=nextjs:nodejs dist/static ./.next/static

USER nextjs

EXPOSE 80

ENV PORT 80

# set hostname to localhost
ENV HOSTNAME "0.0.0.0"

CMD ["node", "server.js"]

/app content:

/app $ find . -maxdepth 2 -type d
.
./.next
./.next/static
./public
./public/flags
./public/icons
./public/img
./dist
./dist/server
./dist/cache
./node_modules
./node_modules/@next
./node_modules/@swc
./node_modules/busboy
./node_modules/caniuse-lite
./node_modules/client-only
./node_modules/glob-to-regexp
./node_modules/graceful-fs
./node_modules/nanoid
./node_modules/next
./node_modules/picocolors
./node_modules/react
./node_modules/react-dom
./node_modules/scheduler
./node_modules/source-map-js
./node_modules/streamsearch
./node_modules/styled-jsx
./node_modules/watchpack

Everything under _next/ path is broken:

❯ curl -I http://test.loc/_next/static/chunks/fd9d1056-a2be535770d9c3e6.js
HTTP/1.1 404 Not Found
Server: nginx/1.21.6
Date: Tue, 09 Jan 2024 18:05:11 GMT
Content-Type: text/html
Content-Length: 1275
Connection: keep-alive
ETag: "620fe3ac-4fb"

What am i doing wrong ?

@paolomainardi
Copy link

paolomainardi commented Jan 9, 2024

Ok i found it:

const distDir = path.join(opts.dir, opts.config.distDir)

IF you specify a custom distDir in the next.config.js file, the static file must be placed there too.

So in my case with a configuration like this:

/** @type {import('next').NextConfig} */
const nextConfig = {
  images: {
    domains: [
      process.env.NEXT_IMAGE_DOMAIN,
      process.env.NEXT_CDN_IMAGE_DOMAIN,
    ],
  },
  distDir: "dist",
  output: "standalone",
};

module.exports = nextConfig;

The working paths must be this:

/app $ find . -maxdepth 2 -type d
.
./.next
./public
./public/flags
./public/icons
./public/img
./dist
./dist/server
./dist/static
./dist/cache
./node_modules
./node_modules/@next
./node_modules/@swc
./node_modules/busboy
./node_modules/caniuse-lite
./node_modules/client-only
./node_modules/glob-to-regexp
./node_modules/graceful-fs
./node_modules/nanoid
./node_modules/next
./node_modules/picocolors
./node_modules/react
./node_modules/react-dom
./node_modules/scheduler
./node_modules/source-map-js
./node_modules/streamsearch
./node_modules/styled-jsx
./node_modules/watchpack

I lost 4 hours of my life for this.

@Lersson
Copy link

Lersson commented Jan 10, 2024

This solution not worked for me! I have https://example/subpath and whe i deploy my app, all the assets _next/static is being pointed to https://example/_next/static and returning 404. My version is Next 14.0.4. Could you help me please to setup this under ngnix-proxy-manager?

@laaragm
Copy link

laaragm commented Jan 25, 2024

I'm also facing this issue with v14.0.4

@elrender
Copy link

elrender commented Feb 9, 2024

IF you specify a custom distDir in the next.config.js file, the static file must be placed there too.

This.

The bug

There is actually a bug in the documentation: https://nextjs.org/docs/app/api-reference/next-config-js/output

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.

It should be noted here that .next directory is actually a default value of distDir and distDir is used in other places during generation of directories.

This is crucial when changing distDir as one must take into account copying static files to a different directory in external scripts. It shouldn't work in a way that forces a developer to remember to change his external scripts everytime he changes NextJS config, notably distDir.

Proposed solution

To mitigate this issue I propose to hardcode third level dist to .next, that is to always have:

./<distDir>/standalone/.next/static

Reasoning

I know that top level dist may be important when one wants to deploy to different providers, but third level dist in the standalone directory is just an internal directory for server.js.

@aytemuryakup
Copy link

aytemuryakup commented Mar 31, 2024

I got a similar error to the one above and tried most of the solutions here, but they didn't solve the problem for me.

Finally, for the standalone build, I was able to provide a solution by copying in my own project as follows. Everything is fine now.

FROM node:18-alpine AS builder


WORKDIR /app
RUN apk add --no-cache libc6-compat
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
RUN npm install --loglevel verbose
COPY . .
RUN npm run build

FROM node:18-alpine AS runner
WORKDIR /app

#ENV NODE_ENV production
# Uncomment the following line in case you want to disable telemetry during runtime.
# ENV NEXT_TELEMETRY_DISABLED 1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
RUN mkdir .next
RUN chown nextjs:nodejs .next


COPY --from=builder --chown=nextjs:nodejs /app/dist/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/dist/.next/static ./dist/.next/static
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
#COPY --from=builder --chown=nextjs:nodejs /app/dist/.next/static ./.next/static

USER nextjs

EXPOSE 3000
ENV PORT 3000
CMD HOSTNAME="0.0.0.0" node server.js

I copied .next/static to .next/standalone/dist/.next and my problem is fixed.

@MaximilienHe
Copy link

This solution not worked for me! I have https://example/subpath and whe i deploy my app, all the assets _next/static is being pointed to https://example/_next/static and returning 404. My version is Next 14.0.4. Could you help me please to setup this under ngnix-proxy-manager?

Did you find a way to get rid of this problem ?

@lucasrosa90
Copy link

Sharing the script I had to write to make this work (next version 13, output directory is called dist):

  "scripts": {
    "deploy": "next build && mkdir -p dist/standalone/public/_next && cp -r dist/static dist/standalone/public/_next/"
  },

Thanks, this worked for me!

Using here:

  • next 14.2.3
  • pnpm 9.1.0
  • (and also pnpm workspaces as it's a monorepo)

vhsdream added a commit to vhsdream/PeaNUT that referenced this issue Jun 5, 2024
the files in .next/static need to be copied to .next/standalone/.next -
ref
vercel/next.js#49283 (comment)

Added relevant copy command to build script in package.json
@hendisantika
Copy link

Sharing the script I had to write to make this work (next version 13, output directory is called dist):

  "scripts": {
    "deploy": "next build && mkdir -p dist/standalone/public/_next && cp -r dist/static dist/standalone/public/_next/"
  },

Thanks, this worked for me!

Using here:

  • next 14.2.3
  • pnpm 9.1.0
  • (and also pnpm workspaces as it's a monorepo)

I'm still having that issue: https://github.com/hendisantika/nextjs-mysql-product-crud

https://products.hendisantika.my.id/products

@george-roussos
Copy link

george-roussos commented Jul 13, 2024

Hi I have stumbled on this problem myself and my app

I am deploying in an Azure container and it works fine (everything loads), but if I try to access my app from a Terraform/ingress domain, I get all 404s

e.g if the domain is mydomain.com/ I get 404s for mydomain.com/_next

I have tried the Dockerfiles here but no luck... Does anyone have any suggestions? I am not using a custom distDir.

EDIT: For anyone testing the solutions above and not getting anywhere and using Ingress/Kube to direct to their app through another domain: check if your requests are being made to proxyUrl/_next instead of deploymentUrl/_next. If the former, there's your culprit and you will need to setup a custom server that serves the static assets off your deployment url

@DatCGI2net
Copy link

DatCGI2net commented Aug 26, 2024

I am on self-hosting, not using vercel service. I faced this issue today. Fortunately, it turned out that the _next/static/media folder was ignored by git. So, just excluded that in the .gitignore file and it's working like charm.

@hendisantika

This comment has been minimized.

@rishi23root
Copy link

i was working with the turbo repo with standalone next app, i got it working👍

# Base stage with Alpine image
FROM node:20-alpine3.17 AS base
WORKDIR /app

# # # Install necessary packages
RUN apk update && apk add --no-cache libc6-compat openssh git

# # # Install pnpm and turbo globally define you specific version according to the package.json
RUN npm install -g pnpm@9.7.0 turbo  
RUN pnpm config set store-dir ~/.pnpm-store

# # #############################################################
# # # Stage 1 - Pruning unnecessary files                       #
# # #############################################################

FROM base AS pruner

# Copy all files to the container and Prune files that are not needed for the specified project
COPY . .
RUN npx turbo prune --scope=web --docker

# # #############################################################
# # # Stage 2 - Installing dependencies and building            #
# # #############################################################

FROM base AS builder
WORKDIR /app
# # Copy lockfile and package.json's of isolated subworkspace
COPY --from=pruner /app/out/pnpm-lock.yaml ./pnpm-lock.yaml
COPY --from=pruner /app/out/pnpm-workspace.yaml ./pnpm-workspace.yaml
COPY --from=pruner /app/out/json/ .

# Install dependencies using pnpm, using a cache for faster builds
RUN --mount=type=cache,id=pnpm-store,target=~/.pnpm-store pnpm install --frozen-lockfile

# # Copy source code of isolated subworkspace
COPY --from=pruner /app/out/full/ .
RUN turbo build --filter=web
RUN pnpm prune --prod --no-optional

# # Cleanup: Remove source files that are not needed
RUN rm -rf ./**/*/src
RUN rm -rf apps/web/.next/standalone/node_modules


# # #############################################################
# # # Stage 3 - Run the application                             #
# # #############################################################

FROM base AS runner

WORKDIR /app/

ENV NODE_ENV="production"

# Copy built files from the builder stage
# COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/ .     

COPY apps/web/public apps/web/.next/standalone/public
RUN mkdir -p apps/web/.next/standalone/public/_next/static
RUN cp -r apps/web/.next/static/* apps/web/.next/standalone/public/_next/static

CMD node apps/web/.next/standalone/server.js

@samcx
Copy link
Member

samcx commented Nov 6, 2024

Hi everyone—

The static files are 404ing because with output: 'standalone', we automatically create a standalone folder that copies only the necessary files for a production deployment including select files in node_modules.

The 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.

To copy these and then start this local minimal server locally, you can do something like this:

pnpm build && cp -r public .next/standalone/ && cp -r .next/static .next/standalone/.next/ && node .next/standalone/server.js

I have also just created a PR to update our documentation with this → #72432.

I see that other folks have already figured out solutions for this. I will closing this PR since this is a non-issue!

@samcx samcx closed this as completed Nov 6, 2024
@ErezGD
Copy link

ErezGD commented Nov 11, 2024

Beware the static files should not always be inserted to the standalone folder, they should actually go into the folder where the project resides which may be different in monorepos. For example, in our case:

COPY --from=builder --chown=nextjs:nodejs /app/pages/backoffice/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/pages/backoffice/.next/static ./pages/backoffice/.next/static

Copy link
Contributor

This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 25, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue was opened via the bug report template. locked Output (export/standalone) Related to the the output option in `next.config.js`.
Projects
None yet
Development

No branches or pull requests