Batuhan Zorbey Zengin
Batuhan Zorbey Zengin

Reputation: 618

I am getting error while converting my next js project to docker

I'm trying to convert my Next js project to Docker. The Dockerfile I got from the next js github page worked fine for me and I got a build successfully.

# Install dependencies only when needed
FROM node:16-alpine AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile

# Rebuild the source code only when needed
FROM node:16-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN yarn build

# Production image, copy all the files and run next
FROM node:16-alpine AS runner
WORKDIR /app

ENV NODE_ENV production

RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

# You only need to copy next.config.js if you are NOT using the default configuration
# COPY --from=builder /app/next.config.js ./
COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./package.json

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

USER nextjs

EXPOSE 3000

ENV PORT 3000

# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry.
# ENV NEXT_TELEMETRY_DISABLED 1

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

I wrote this later.

docker run -p 3000:3000 imagename

Then I faced such error and I can't solve it.

node:internal/modules/cjs/loader:936
  throw err;
  ^

Error: Cannot find module '/app/server.js'
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
    at node:internal/main/run_main_module:17:47 {
  code: 'MODULE_NOT_FOUND',
  requireStack: []
}

I searched a lot on the internet but couldn't find much. What do you think I should do?

Upvotes: 47

Views: 65258

Answers (13)

Gokul Narayan
Gokul Narayan

Reputation: 1

Adding this environment variable in the Dockerfile solved the issue

ENV NEXT_PRIVATE_STANDALONE true

Add this before the build step

Upvotes: 0

Invincibear
Invincibear

Reputation: 159

If you're using a modern version of Next.js that uses next.config.mjs instead of next.config.js, here is the new syntax so that build (not dev) runs export as standalone packages:

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: "standalone",
}

export default nextConfig;

Upvotes: 3

Shivam kaushal
Shivam kaushal

Reputation: 326

If you are using Nextjs with page router then you need to add this code to the next.config.js file

module.exports = {
  output: 'standalone'
}

if you are using app router then you need to add this code to the next.config.mjs file

const nextConfig = {
  output: 'standalone'
};

export default nextConfig;

Upvotes: 5

Ludo237
Ludo237

Reputation: 1727

If you still having issues with Next 14 or newer versions this fixed the problem

NEXT_PRIVATE_STANDALONE=true npm run build

You can also include this in your dockerFile as well

... other stages
FROM base as BUILDER

ENV NEXT_PRIVATE_STANDALONE true

COPY --from=DEPENDENCIES /src/application/node_modules ./node_modules
COPY . .

RUN npm run build
...other stages

To this day this is the only solution that works, Nextjs 14 seems to ignore the output: 'standalone' configuration

Upvotes: 10

Martin
Martin

Reputation: 7011

My issue was Mounted path. Please check Your: docker-compose.yml file for possibly collision with mounting points at file's part: volumes. Simple, but it takes me time to find it ☺️

Upvotes: 0

Niks
Niks

Reputation: 41

I am using nextJs 13.1.1 and facing same issue when trying with docker and output: 'standalone'. It seems mounted folders in container and files are facing this Module not found error if not specified in docker volumes.

 volumes:
  - /usr/src/app/build

I added build as volume in docker compose and moved standalone and rest of the content to build in place of root of the working directory. Now it's working.

COPY --from=build_stage /usr/src/app/package*.json ./build
COPY --from=build_stage /usr/src/app/public ./build/public
COPY --from=build_stage /usr/src/app/next.config.js ./build
COPY --from=build_stage /usr/src/app/.env* ./build

COPY --from=build_stage --chown=appuser:appcontainer /usr/src/app/.next/standalone ./build
COPY --from=build_stage --chown=appuser:appcontainer /usr/src/app/.next/static ./build/.next/static

Upvotes: 0

viren
viren

Reputation: 44

In my case, I was using a next.js image so I needed to install the sharp module also.

Upvotes: 0

Joshua Davis
Joshua Davis

Reputation: 1056

Ensure that you're copying all files from the example. In this case you need to ensure you have added or customized next.config.js with this:

module.exports = {
  output: 'standalone'
}

You'll notice the file is also defined in the examples: https://github.com/vercel/next.js/blob/canary/examples/with-docker/next.config.js

Upvotes: 93

EcksDy
EcksDy

Reputation: 1664

TL;DR
My next is version 11, with-docker example is version 12.

I've looked at the history of the Dockerfile in the official Next.js with-docker example. There I've noticed the addition of these lines to the Dockerfile, and the addition of experimental flag outputStandalone.

This flag is available from next@12 while my project is next@11, so undoing these lines in my Dockerfile solved the issue.

Going over that file history can give insight on different issues.

Upvotes: 1

Michael Oryl
Michael Oryl

Reputation: 21662

The answer depends on which version of Next you are running. First of all, you need to uncomment the line in your Dockerfile that copies server.js (and the rest of the .next/standalone folder) to /app.

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

Then you need to include one of the following in your next.config.js files, depending on the version of Next you are running.

If you are running Next 12.1.x or earlier, then you need this:

module.exports = {
  experimental: {
    outputStandalone: true,
  },
}

If you are running 12.2.x or later, use this:

module.exports = {
  output: 'standalone',
}

This will cause .next/standalone to be created, and that folder includes server.js so that when the COPY command runs, it and the subfolders get placed into /app.

Upvotes: 30

Cristian Lazo
Cristian Lazo

Reputation: 123

I had the same problem and the conflict was that I was using Next 11 instead 12, you can use this dockerfile which runs perfect with Next 11 or try the following code.

# Install dependencies only when needed
FROM node:14-alpine AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile

# Rebuild the source code only when needed
FROM node:14-alpine AS builder
WORKDIR /app
COPY . .
COPY --from=deps /app/node_modules ./node_modules
RUN yarn build

# Production image, copy all the files and run next
FROM node:14-alpine AS runner
WORKDIR /app

ENV NODE_ENV production

RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

# You only need to copy next.config.js if you are NOT using the default configuration
# COPY --from=builder /app/next.config.js ./
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json

USER nextjs

EXPOSE 3000

ENV PORT 3000

# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry.
# ENV NEXT_TELEMETRY_DISABLED 1

CMD ["node_modules/.bin/next", "start"]

Upvotes: 1

Lucas Santana
Lucas Santana

Reputation: 21

Just change nextjs version in package.json file to latest and run yarn install. Now docker build work fine.

Upvotes: 2

Batuhan Zorbey Zengin
Batuhan Zorbey Zengin

Reputation: 618

FROM node:14-alpine AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json ./
RUN npm install --frozen-lockfile
RUN npm i [email protected]

# Rebuild the source code only when needed
FROM node:14-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN yarn build

# Production image, copy all the files and run next
FROM node:14-alpine AS runner
WORKDIR /app

ENV NODE_ENV production

RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

# You only need to copy next.config.js if you are NOT using the default configuration
COPY --from=builder /app/next.config.js ./
COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/.env ./

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

USER nextjs

EXPOSE 3000

ENV PORT 3000

# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry.
# ENV NEXT_TELEMETRY_DISABLED 1

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

Solved my problem this is the new Dockerfile and it works for me.

Upvotes: 3

Related Questions