skip to Main Content

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?

6

Answers


  1. Chosen as BEST ANSWER
    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.


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

    Login or Signup to reply.
  3. 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.

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

    Login or Signup to reply.
  5. 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"]
    
    Login or Signup to reply.
  6. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search