DEV Community

Shanu
Shanu

Posted on

How to Dockerize a Next.js Application

Setting up a Next.js application with Docker can greatly enhance your development workflow by ensuring consistent environments and simplifying deployment. This guide will take you through the steps to Dockerize a Next.js application, from setting up Docker to building and running Docker images.

Prerequisites

  • Docker: Ensure Docker is installed on your machine. You can download it from Docker's official website.
  • Next.js Application: You should have a Next.js application created using create-next-app or another method. If you don't have one, you can create a basic app using create-next-app.
npx create-next-app my-next-app
cd my-next-app
Enter fullscreen mode Exit fullscreen mode

Step 1: Create a Dockerfile

A Dockerfile contains a series of instructions to build a Docker image for your application. In the root directory of your Next.js application, create a file named Dockerfile with the following content:

# Use an official node runtime as a parent image
FROM node:20-alpine

# Set the working directory
WORKDIR /app

# Copy the package.json and package-lock.json files to the working directory
COPY package*.json ./

# Install the dependencies
RUN npm install

# Copy the rest of the application code to the working directory
COPY . .

# Build the Next.js app
RUN npm run build

# Start the Next.js app
CMD ["npm", "start"]

# Expose port 3000
EXPOSE 3000
Enter fullscreen mode Exit fullscreen mode

Step 2: Create a .dockerignore File

A .dockerignore file specifies which files and directories should be ignored when copying files to the Docker image. This helps reduce the image size and speed up the build process. Create a .dockerignore file in the root directory with the following content:

node_modules
.dockerignore
Dockerfile
.git
.gitignore
.next
Enter fullscreen mode Exit fullscreen mode

Step 3: Build the Docker Image

To build the Docker image for your Next.js application, navigate to the root directory of your application and run the following command:

docker build -t my-next-app .
Enter fullscreen mode Exit fullscreen mode

This command tells Docker to build an image with the tag my-next-app using the current directory (.) as the context.

Step 4: Run the Docker Container

Once the Docker image is built, you can run it in a container using the following command:

docker run -p 3000:3000 my-next-app
Enter fullscreen mode Exit fullscreen mode

This command maps port 3000 on your local machine to port 3000 in the container, allowing you to access the Next.js application in your browser at http://localhost:3000.

Step 5: Docker Compose (Optional)

If you want to manage multiple containers or add more configuration, you can use Docker Compose. Create a docker-compose.yml file in the root directory with the following content:

version: '3'

services:
  next-app:
    build: .
    ports:
      - "3000:3000"
Enter fullscreen mode Exit fullscreen mode

To start the services defined in the docker-compose.yml file, run the following command:

docker-compose up
Enter fullscreen mode Exit fullscreen mode

Conclusion

By following these steps, you have successfully Dockerized your Next.js application. Dockerizing your application not only ensures consistency across different environments but also simplifies the deployment process, making it easier to manage and scale your application.

Additional Resources

Feel free to customize the Dockerfile and Docker Compose configuration according to your project's specific needs. Happy Dockerizing!

Top comments (24)

Collapse
 
samurai71 profile image
Mark Landeryou

I'm currently looking at learning docker however what are the advantages of using docker ?

Collapse
 
ezpieco profile image
Ezpie

quite a lot, I will use a scenario to explain, imagine you have to maintain legacy code, it uses node version 14, but as we all know node has skyrocketed to version 22.5.1, now how are you going to maintain legacy code? Well you could just install node 14, but that would mean you would need to get rid of node 22, to overcome this, you could just use docker, docker would create a kind of computer on your computer that has node version 14 installed in it with the source code, like this you can run the legacy app without having version conflicts.

A more practical example would be having to run a whole backend, imagine you are a frontend engineer, you need to use the backend, fully(which is the worst thing), now the backend has a lot of dependencies, python, rust, java, all 3 of them are being used, why? Because your backend team decided to go microservice that's why, you need the APIs and functionality, how are you going to get that? Docker it! You can install docker and docker will run each microservice as per your backend teams configurations, all you have to do, is run the container and hoping that your backend team has made proper configs which are automated, you won't need to do much work.

Collapse
 
ashishsimplecoder profile image
Ashish Prajapati

i understand it now clearly

Collapse
 
shanu001x profile image
Shanu

Excellent examples! Docker truly shines when dealing with legacy code and complex backend setups. Using Docker to manage different Node versions avoids conflicts, and for microservices, it simplifies running and integrating diverse dependencies. These scenarios highlight Docker’s flexibility and efficiency in handling various development and operational challenges. Thanks for illustrating these use cases!

Thread Thread
 
weaponsforge profile image
Weapons Forge

Bonus points! I love how it greatly helps code portability and consistency across environments. Another thing I liked about it is, it provides a layer of protection against supply chain attacks when installing NPM (or Python) dependenciesβ€”they are installed in the container instead of directly on my development PC or laptap.

Collapse
 
samurai71 profile image
Mark Landeryou

Thanks that makes sense . I love the scenario it helped me see the use

Collapse
 
denys_bochko profile image
Denys Bochko

I think one of the main advantages is that you can run identical containers for local dev and production.
I am coming from backend background and a lot of times when the production has different updates than the local environment, that's a big problem.
You can either create a docker container from the same dockerfile locally and in production or create it ones and then use in multiple places.

As it was mentioned before version testing is another great feature, that I actually used.

Collapse
 
samurai71 profile image
Mark Landeryou

I was looking at learning it however know I will learn it. However now I have a question say you are developing on local machine which is windows but server is Linux can docker run Linux without installing it?

Thread Thread
 
denys_bochko profile image
Denys Bochko

You are asking the wrong question. Docker is a technology that allows you to run specific services inside of your containers. You are not looking to run Linux or ubuntu, you are looking to run what you need to have: apache server, nodejs, react or python, mysql, postress, you name it.
Then you look to see if there are already existing docker images with for that kind of development. Most likely there is. So you just use it to run a container using that image on your local machine.

Windows runs docker, so you can run whatever service you need to run in docker on windows. You can run a lot of things in docker without installing them locally.

Thread Thread
 
samurai71 profile image
Mark Landeryou

Oh okay my apologies I am trying to get this and learn

Thread Thread
 
denys_bochko profile image
Denys Bochko

I suggest taking a course on docker. one on udemy from Academind helped me. You will get a much clear picture of the technology and how to use it.

Collapse
 
shanu001x profile image
Shanu

Docker provides consistency across environments, isolation of applications, and easy portability. It also allows for efficient resource use and simplifies dependency management.

Collapse
 
ed1nh0 profile image
Edson Jr.

I'm a frontend developer and I'm using Vercel to deploy simple NextJS apps. As for learning purposes I think using Docker isn't necessary, am I right? In what scenario or case should I use it? Thanks in advance.

Collapse
 
denys_bochko profile image
Denys Bochko

It depends. I am using docker to develop vue.js apps. The advantage of using docker is that I don't have to install node locally on my machine, it's all done in docker containers.
It is better for organization purposes as you can setup a docker-compose which serves as a separate network to host your db, api and frontend. That separates it from the rest of your projects, so there is no mess. You can also use docker with the same project to upgrade node or any framework you are using keeping the original project intact and trying the new things in a separate docker container.

Collapse
 
shanu001x profile image
Shanu

Great points! Docker indeed offers fantastic benefits for development, such as avoiding local dependencies and maintaining a clean and organized environment. The use of docker-compose for managing different components and the flexibility to upgrade frameworks without affecting your main setup are invaluable. Thanks for sharing your experience with Docker for Vue.js apps!

Collapse
 
ed1nh0 profile image
Edson Jr.

Well as per Vercel's documentation, it does not support running docker instances, but I can run it locally for practice purposes. Thank you.

vercel.com/guides/does-vercel-supp...

Thread Thread
 
denys_bochko profile image
Denys Bochko

I think there are two questions merged in your post. For learning purposes using Docker with your Nextjs app is a great idea as Docker is being asked by many companies as it is a great containerization tool. One of the main features of docker is that you can have local dev and prod dev using the same container setup which would improve quality of your releases.
Vercel is a cloud offering so of course it does not support docker as it is a platform on its own. I would not be surprised if they themselves use docker. It is similar to other hosting providers but one that already has Nodejs preinstalled. So, it's no surprise it does not support docker.
I heard about Vercel before, but I prefer to have the local dev done on the local machine, so I can even when there is no internet and have my code in git.
It is simply a matter of preference. :)

Thread Thread
 
ed1nh0 profile image
Edson Jr.

Well explained! Thanks a lot for your attention!

Collapse
 
denys_bochko profile image
Denys Bochko

I have a similar guide on github going a bit further with automation so you don't have to work with docker file, but simply setup your project name and port to use on your app and it will create the containers and create files to run them.

Collapse
 
shanu001x profile image
Shanu

That sounds fantastic! Automation can really simplify the process. Could you share the link to your guide? I'd love to check it out and learn more about your approach.

Collapse
 
denys_bochko profile image
Denys Bochko
Collapse
 
joseph_gitonga_08483a40cf profile image
Joseph Gitonga

This is OK for non-production app. However, it's good to consider optimization via multi-step build, running the app as non-root user, using pm2 for running the app, among other best practices βœ…

Collapse
 
shanu001x profile image
Shanu

Thank you for your feedback! You’re absolutely right. For a production-ready setup, optimizing the Dockerfile with multi-stage builds, running the application as a non-root user, and using tools like PM2 are indeed best practices that enhance performance, security, and maintainability. I’ll consider incorporating these points in future updates or articles. Thanks for contributing to the discussion!

Collapse
 
shusain_d54c3f4df3007d80 profile image
s.husain

yrs