Next.js multi-stage Docker file

The example Dockerfile on the next.js website didn’t work for me. So after some tweaking, and turning it into a multistage Dockerfile to slim it down, I thought I’d share it in case someone else ran into the same problem.

This is a multi-stage Dockerfile split into the following three stages:

  • The first stage installs some packages for the Alpine Node image andcreates a working directory for the app. The Node packages are then installed after copying the package.json and yarn.lock file.
  • The second stage copies the Node modules from the deps stage, then copies all files in the directory the Dockerfile is in. yarn build is called to build the source code.
  • The last stage installs some packages and creates a non-root user to run as, then copies necessary from the builder stage. A .env file is copied from the same directory as the Dockerfile. The yarn serve command calls the serve script in package.json which calls next start . This starts the application in production mode.
# Install dependencies only when needed
FROM node:14.16.1-alpine AS deps
RUN apk add --no-cache libc6-compat nasm autoconf automake bash libltdl libtool gcc make g++ zlib-dev
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --network-timeout 1000000
# ==================================================================
# Rebuild the source code only when needed
FROM node:14.16.1-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# 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 during the build.
# ENV NEXT_TELEMETRY_DISABLED 1
RUN yarn build# ==================================================================
# Production image, copy all the files and run next
FROM node:14.16.1-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 apk add --no-cache libc6-compat nasm autoconf automake bashRUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
# 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/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY .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 nextjsEXPOSE 3000ENV PORT 3000# CMD ["node", "server.js"]
CMD ["yarn", "serve"]

Hope you found this useful!
Cheers 🤙

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store