How to run your Next.js app in Docker

Running a Next.js application in Docker greatly simplifies maintenance and portability. Let us have a detailed look into how to create a production ready Dockerfile. We will start out by creating the simplest version possible and then add layer caching and a .dockerignore file.

Deploying a Next.js application to a server can be greatly simplified by using Docker. Since Docker makes our lifes so much easier when it comes to maintenance and portability of an application, we will have a closer look into how we can create and run a Docker Image for our Next.js applications.

Building and Running a Next.js project in Docker

After installing Docker we can get started with creating our Dockerfile, which tells Docker how to create a Docker Image from our project.

Creating a Dockerfile

We will put our Dockerfile in the root directory of the Project we want to dockerize. Let's say your project is located in /home/manuel/awesomeapp, in this case we would need to create a file with the location /home/manuel/awesomeapp/Dockerfile .

A simple Dockerfile

For the simple approach our Dockerfile would contain the following content:

FROM node:lts-buster
WORKDIR /app
COPY . .
RUN npm install && \
    npm run build
EXPOSE 3000
ENTRYPOINT ["npm", "run", "start"]

Great! Are we done?
Well... not exactly. One thing we want to definitely take advantage of is Docker's built in capability for layer caching. This mechanism allows us to not have to rebuild layers that haven't changed and results in much faster builds.

With Layer Caching

A common practice in Dockerfiles is to cache the dependencies of a project. In our case the node_modules defined by our package.json file. As long as we have no changes in our package.json, each build will be able to reuse the previously downloaded node_modules.

FROM node:lts-buster
WORKDIR /app
COPY package.json ./
RUN npm install
COPY . .
RUN npm run build
EXPOSE 3000
ENTRYPOINT ["npm", "run", "start"]

.dockerignore

Currently we are still copying all files to our Docker Image, which might take longer than necessary. To avoid this problem we should tell Docker to ignore the files for our build, by creating a .dockerignore file and placing it next to our Dockerfile.

node_modules
.next

Running the build

With our Dockerfile and .dockerignore files all ready and set, we are finally able to build our precious Docker Image by running

docker build -t tutorialapp

Here tutorialapp is an arbitrary tag we chose, feel free to use any name you like.

Running the Docker Image

docker run -p 3000:3000 tutorialapp .
(Note the dot at the end of the command)

docker pull tutorialapp