Next.js is a popular React framework known for its capabilities in server-side rendering, static site generation, and creating efficient web applications. Docker, on the other hand, is a powerful tool that allows developers to containerize applications, ensuring that they run consistently across different environments. By combining these two, developers can enhance the scalability, reproducibility, and deployment ease of their Next.js applications. In this article, we’ll explore how to dockerize a basic Next.js application, making it ready for development and production environments.

Step 1: Setting Up Your Next.js Application

First, let’s create a new Next.js project if you haven’t done so already. You can skip this step if you already have a Next.js app.
npx create-next-app my-nextjs-app
cd my-nextjs-app
This command sets up a new Next.js application in the directory my-nextjs-app.

Step 2: Creating the Dockerfile

A Dockerfile contains all the commands a user could call on the command line to assemble an image. Here’s how to create one for a Next.js app:
# Define the base image as node:20 and name it as base.
FROM node:20 AS base

# Set the working directory inside the container to /app.
# We need to set the working directory so Docker knows where to run the commands.
WORKDIR /app

# Globally install the package manager pnpm.
RUN npm i -g pnpm

# Copy the package.json and pnpm-lock.yaml files to the working directory in the container.
# This command is necessary for Docker to install project dependencies.
COPY package.json pnpm-lock.yaml ./

# Install project dependencies using pnpm.
RUN pnpm install

# Copy all files from the context directory (where the Dockerfile is located) to the working directory in the container.
COPY . .

# Run the project build command using pnpm.
RUN pnpm build

# Define a second stage of the image based on node:20-alpine and name it as release.
# Alpine image is a lighter version of node, which helps reduce the final image size.
FROM node:20-alpine as release

# Set the working directory inside the container to /app.
WORKDIR /app

# Globally install the package manager pnpm.
RUN npm i -g pnpm

# Copy the node_modules folder from the base stage to the node_modules directory in the release stage.
COPY --from=base /app/node_modules ./node_modules

# Copy the package.json file from the base stage to the current directory in the release stage.
COPY --from=base /app/package.json ./package.json

# Copy the .next folder from the base stage to the .next directory in the release stage.
COPY --from=base /app/.next ./.next


# Define the default command to be executed when the container is started with pnpm start.
CMD ["pnpm", "start"]

Step 3: Building and Running Your Docker Container

Now, build the Docker image using the following command:
docker build -t my-nextjs-app .
After the image is built, run your container:
docker run -p 3000:3000 my-nextjs-app
This command runs your container and maps port 3000 of the container to port 3000 on your host, allowing you to access the Next.js application by navigating to http://localhost:3000 on your web browser.

Docker Cheat Sheet

Here are some useful commands for managing Docker containers:

– View all running containers docker ps -a – To stop a container, execute the command docker stop – Stop all running Docker containers docker stop $(docker ps -a -q) – To remove a container, execute the command docker rm – Remove all Docker containers docker rm $(docker ps -a -q) – Remove all stopped Docker containers docker container prune – To view the images on your system, execute the command docker image ls – To remove an image, execute the command docker image rm : -If the image is being used by a container, you must stop and remove the container before removing the image. Another way is to add the -f flag to force removal. docker image rm -f : – To remove all images, execute the command docker rmi $(docker images -q)