-
Notifications
You must be signed in to change notification settings - Fork 18
6. Docker
This repository comes with Docker configuration files to enable you to build and run the Next.js application in a Docker container, a lightweight, stand-alone, and executable package that includes everything needed to run a piece of software, including the code, a runtime, libraries, environment variables, and config files.
The Docker related files are located within the docker
directory at the root of the repository. The docker
directory has the following structure:
docker/
├── docker-compose.yml
└── next/
└── Dockerfile
-
docker-compose.yml
: Docker Compose file for orchestrating multi-container Docker applications. -
next/Dockerfile
: Dockerfile for the Next.js application.
Docker Compose is a tool that allows us to define and manage multi-container Docker applications. It uses YAML files to configure the application's services and performs the creation and start-up process of all the containers with a single command.
In this project, the docker-compose.yml
file is configured to run the Next.js application.
Here is a breakdown of what each part does:
version: '3' # The version of Docker Compose to use
services: # Define the services that should be created
nextjs: # The name of the first service
build: # Specifies the options that Docker should use when building the Docker image
context: .. # The build context specifies the location of your source files
dockerfile: docker/next/Dockerfile # The name and location of the Dockerfile
ports: # Expose ports
- 3000:3000 # Maps the internal Docker host port 3000 to the external Docker client port 3000
By using this docker-compose.yml
, you can bring up your entire app by using the command docker-compose up
and bring it down using docker-compose down
from the directory that contains the docker-compose.yml
file. This will take care of all the intricacies of setting up the Next.js service.
This Dockerfile utilizes a multi-stage build process. In a multi-stage build, you use multiple FROM
statements in your Dockerfile. Each FROM
statement can use a different base, and each of them begins a new stage of the build. You can selectively copy artifacts from one stage to another, leaving behind everything you don’t want in the final image.
Multi-stage builds are useful to anyone who has struggled to optimize Dockerfiles while keeping them easy to read and maintain.
Below is a line-by-line explanation of each part of the Dockerfile
.
# ---- Build Stage ----
FROM node:18.16.0-alpine AS builder
This is the first stage of the multi-stage build. It uses the node:18.16.0-alpine
Docker image as the base image. This image includes Node.js based on the 18.16.0 version and uses Alpine, a lightweight Docker image. The stage is named builder
.
WORKDIR /app
Set the working directory to /app
. All the instructions that follow in the Dockerfile
will be run from this directory.
COPY package*.json ./
Copy the package.json
and package-lock.json
(if available) from your host to your image filesystem.
RUN npm install
Run the npm install
command inside your image filesystem which installs the dependencies described in package.json
.
COPY . .
Copy everything from the current directory in your host to the WORKDIR
in your image filesystem.
RUN npm run build
This step will create an optimized production build of your Next.js application.
# ---- Release Stage ----
FROM node:18.16.0-alpine AS release
This begins the second stage of the multi-stage build, also using node:18.16.0-alpine
as the base image, named as release
.
WORKDIR /app
Sets the working directory to /app
.
COPY --from=builder /app/package*.json ./
This copies the package.json
and package-lock.json
(if available) from the builder
stage to the current stage.
RUN npm install --only=production
This will install only the dependencies needed for running the application, and not the devDependencies, thus creating a leaner image.
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/public ./public
These lines are copying the built Next.js app files and the public files from the builder
stage into the release
stage.
EXPOSE 3000
This informs Docker that the container listens on the specified network ports at runtime. In this case, it's port 3000.
CMD ["npm", "start"]
Provides defaults for executing a container, which includes the specifications of what executable to run when the container starts.
In conclusion, this Dockerfile leverages the multi-stage build feature to create a lean, production-ready Docker image of your Next.js application. You start with a larger image containing everything needed to build your application, and then copy just the built application and its runtime dependencies into a smaller, final image.