How to dockerize your Next js app in 3 simple steps
March 18, 2023

Docker has become a popular tool for modern web development, allowing developers to create and deploy applications consistently across different environments. Dockerizing your Next.js application can provide many benefits, such as consistency, portability, and scalability. In this blog post, we will explore how to dockerize a Next.js application and take advantage of Docker's benefits.
Overview
Steps:
Create a Dockerfile for Next js
The first step is to create a Dockerfile, which is a script that contains instructions for building a Docker image. Here's an example Dockerfile for a Next.js application:
FROM node:18-alpine AS base
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
RUN yarn --frozen-lockfile
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
FROM base AS runner
WORKDIR /app
ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
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
CMD ["node", "server.js"]
Above is an example of multi-stage build Dockerfile. Here's a breakdown of what each section of the Dockerfile does:
FROM node:18-alpine AS base: This sets the base image for the Dockerfile tonode:18-alpine, which is the official Node.js 18 Alpine image.FROM base AS deps: This creates a new stage in the Dockerfile, using thebaseimage as the base image for this stage. In this stage, we install any dependencies required for the Next.js application. We first installlibc6-compatpackage, which provides compatibility for programs that use glibc. Then we set the working directory to/appand copy over thepackage.json,yarn.lock,package-lock.json, andpnpm-lock.yamlfiles. Finally, we install the dependencies usingyarn.FROM base AS builder: This creates another stage in the Dockerfile, using thebaseimage as the base image for this stage. In this stage, we copy over the files from the previous stage, including the installed dependencies. We then run thenpm run buildcommand to build the Next.js application.FROM base AS runner: This creates the final stage in the Dockerfile, using thebaseimage as the base image for this stage. In this stage, we set the working directory to/app, set theNODE_ENVenvironment variable toproduction, and disable Next.js telemetry. We then create anodejsgroup with a GID of1001and anextjsuser with a UID of1001. We copy over the built Next.js application files from thebuilderstage, set the user tonextjs, expose port3000, set thePORTenvironment variable to3000, and specify the command to run the Next.js server.
Why use multi-stage Dockerfile?
Multi-stage builds in Docker are used to optimize the size of the resulting image and reduce the attack surface. When building a Docker image, each layer added to the image adds size, which can slow down development and deployment processes. Multi-stage builds help to solve this problem by allowing for the creation of multiple stages in the Dockerfile, each of which can have a different base image and set of instructions. Each stage creates a separate layer in the resulting image, but you can choose which layers to keep and which to discard. This approach helps to minimize the size of the resulting image and reduce the attack surface by including only what is necessary to run the application in production. Overall, multi-stage builds are an important tool for optimizing Docker images and making them more efficient and secure.
Build the Docker Image
Once you've created the Dockerfile, you can build the Docker image using the docker build command. Here's an example command:
docker build -t my-next-app .
In this command, we're using the -t flag to specify the name of the Docker image (my-next-app), and the . at the end specifies the location of the Dockerfile (in the current directory).
To check docker images, run below command:
docker images

Run the Docker Container
After building the Docker image, you can run the Docker container using the docker run command. Here's an example command:
docker run -p 3000:3000 -d my-next-app
In this command, we're using the -p flag to map the container's port 3000 to the host machine's port 3000, -d is to run the container in background, and my-next-app specifies the name of the Docker image we want to run.
To check running containers, run the below command:
docker ps

To check logs, run the below command:
docker logs -f 5156a31ad3a5 #replca with your container id/name
In this command, we're using -f to get the running logs, and "5156a31ad3a5" is a container id you can also use container name instead of id.
To access your application, open your browser and go to http://localhost:3000