Unhandled Runtime Error ChunkLoadError

Hello,
The Dockerfile is:

FROM node:23-alpine
# Install latest npm
RUN npm install -g npm@latest
# Create app directory and set proper permissions
RUN mkdir -p /app && chown -R node:node /app
WORKDIR /app
# Copy package files and install dependencies
COPY --chown=node:node package*.json ./
RUN npm install --legacy-peer-deps
# Copy app files
COPY --chown=node:node . .
# Ensure the .next directory exists and has proper permissions
RUN mkdir -p .next && chown -R node:node .next
USER node
ENV NODE_ENV=development
ENV CHOKIDAR_USEPOLLING=true
EXPOSE 3000
CMD ["npm", "run", "dev"]

Every time I open a page, the following error appears and I have to refresh the page:

Where is the misconfiguration?

Thank you.

The fact that the app is trying to load JavaScript chunks from the file system (file://) seems wrong to me. In a typical Next.js development environment, JavaScript chunks are served via HTTP, e.g. as http://localhost:3000/_next/static/chunks/..... That kind of path (file:///app/.next/...) may indicate that something has gone wrong with how the app is being run inside Docker.

Most likely, it’s trying to execute frontend code before the dev server is ready, or the chunk paths are being resolved incorrectly because of how the container is configured. You might be mounting or copying .next in a way that confuses the runtime.

Try removing .next entirely (rm -rf .next) and let the dev server rebuild it from scratch inside the container, not copied from your host.

2 Likes

Hello,
Thank you so much for you reply.
The compose file is:

portal:
    container_name: portal
    restart: unless-stopped
    build:
      context: /home/Projects/portal/
      dockerfile: Dockerfile
    environment:
      - NODE_ENV=development
      - WATCHPACK_POLLING="false"
      - FAST_REFRESH="true"
      - NEXT_TELEMETRY_DISABLED=1
      - MAX_OLD_SPACE_SIZE=4096
      - GENERATE_SOURCEMAP=false
      - INLINE_RUNTIME_CHUNK=false
      - USER_ID=${USER_ID:-999}
      - GROUP_ID=${GROUP_ID:-995}
    user: "${USER_ID:-999}:${GROUP_ID:-995}"
    volumes:
      - /home/Projects/portal:/app
      - /app/node_modules          
      - portal-next:/app/.next

And Dockerfile is:

FROM node:23-alpine

ARG USER_ID=999
ARG GROUP_ID=995

RUN addgroup -g ${GROUP_ID} appuser && \
    adduser -S -u ${USER_ID} -G appuser appuser

WORKDIR /app

COPY package*.json ./

RUN npm install -g npm@latest && \
    npm install --legacy-peer-deps

COPY --chown=${USER_ID}:${GROUP_ID} . .

RUN mkdir -p /app/.next && \
    chown -R ${USER_ID}:${GROUP_ID} /app/.next

#COPY --chown=${USER_ID}:${GROUP_ID} . .

RUN chown -R ${USER_ID}:${GROUP_ID} /app/node_modules

USER ${USER_ID}

EXPOSE 3000

CMD ["npm", "run", "dev"]

In the /home/Projects/portal directory, there is a .next directory that is empty. The contents of the .dockerignore file are as follows:

.git
.idea
node_modules
.next
*.md
*.log
Dockerfile
.gitlab-ci.yml
.editorconfig
.eslintrc.json
.prettierrc

What is wrong?

I think that the issue is that you’re mounting an external volume to /app/.next, but that volume is empty. This overwrites the internal .next directory that Next.js needs to serve chunks, leading to the file:// errors you’re seeing.

To fix:

  • Remove this line from your docker-compose file: - portal-next:/app/.next.
  • Delete any .next directory on your host: rm -rf /home/Projects/portal/.next
  • Rebuild the container: docker-compose build --no-cache
  • And restart the service: docker-compose up

Let the dev server create and manage .next inside the container. That should hopefully resolve the chunk loading problem.

Let us know how it goes.

Hello,
Thanks again.
But it’s the exact opposite. If I remove that line, the .next directory is created on the host, not the container. Meanwhile, the .dockerignore file prevents the .next directory on the host from replacing the .next directory in the container.

Contents of the .next directory in the container:

$ ls .next
app-build-manifest.json       server
build-manifest.json           static
cache                         trace
package.json                  types
react-loadable-manifest.json

Does that seem right?

Out of curiosity, did you try the steps I posted earlier?

It would be good to know if that made a difference, and if not, what exactly happened.

Hello,
Thanks again.
I did. This will create the .next directory with root permissions on the host.

I think that the reason .next is showing up on your host with root permissions is because you’re bind-mounting the entire project folder with this line:

- /home/Projects/portal:/app

That causes anything created inside the container to appear on your host, which leads to permission issues and possibly chunk loading problems.

To see if this is the root cause of the error:

Comment out the following (temporarily):

#- portal-next:/app/.next
#- /home/Projects/portal:/app

Then rebuild and restart:

docker-compose build --no-cache
docker-compose up

Then check: does the chunk loading error still appear? This test will tell if the mount setup is causing the issue. Let us know the result.