Reputation: 618
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
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
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
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
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
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
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
Reputation: 44
In my case, I was using a next.js
image so I needed to install the sharp
module also.
Upvotes: 0
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
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
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
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
Reputation: 21
Just change nextjs
version in package.json file to latest
and run yarn install
. Now docker build work fine.
Upvotes: 2
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