Go Back

TECH+++

Article

Why Docker & How to Dockerize a NextJS App

Why Use Docker?

When you work as a software engineer, having a reliable development environment is crucial. Engineers should be able to work without worrying about their Node.js version or manually installing dependencies. This is where Docker comes in. Docker is a powerful tool that simplifies software deployment by containerizing applications and their dependencies.

Here’s why Docker is essential:

  1. Consistency Across Environments: Docker ensures your application behaves the same way across different systems, eliminating the "it works on my machine" issue.

  2. Simplified Dependency Management: Docker encapsulates dependencies, avoiding manual setup.

  3. Efficient Resource Utilization: Docker containers are lightweight and share the host OS kernel, unlike traditional virtual machines.

  4. Scalability and Deployment: Docker enables horizontal scaling with tools like Docker Swarm and Kubernetes.

  5. Portability: Containers can seamlessly move between development, staging, and production environments.

How to Dockerize a Next.js App

Here’s a step-by-step guide to containerizing a Next.js app using Docker.

1. Create a Next.js App

If you don’t already have one:

1npx create-next-app@latest my-next-app 2cd my-next-app

2. Create a Dockerfile

In your project root:

1# --- Base Image --- 2FROM node:20.18.0-bookworm AS base 3 4# --- Set Environment Variables --- 5ENV NODE_ENV=development \ 6 SHELL=/bin/bash \ 7 TMP_DIR=/mnt/tmp \ 8 WORKDIR=/app 9 10WORKDIR ${WORKDIR} 11 12# --- System Dependencies --- 13RUN apt-get update && apt-get install -y tini && rm -rf /var/lib/apt/lists/* 14 15# --- Install pnpm --- 16RUN npm install -g pnpm@9.14.1 17 18# --- Set Up pnpm Cache --- 19ENV npm_config_cache="${TMP_DIR}/npm-cache" \ 20 npm_config_store_dir="${TMP_DIR}/pnpm-store" 21 22# Copy dependency files and install packages 23COPY package.json pnpm-lock.yaml ./ 24RUN pnpm install --frozen-lockfile 25 26# Copy app source code 27COPY . . 28 29# --- Development Stage --- 30FROM base AS dev 31CMD ["pnpm", "dev"] 32 33# --- Production Stage --- 34FROM base AS prod 35ENV NODE_ENV=production 36RUN pnpm run build 37CMD ["pnpm", "start"] 38 39# Use tini for process management 40ENTRYPOINT ["/usr/bin/tini", "-sg", "--"] 41 42EXPOSE 3000

3. Create .dockerignore

To reduce build context:

1node_modules 2build 3.dockerignore 4Dockerfile 5docker-compose.yml 6.git

4. Create docker-compose.yml

1services: 2 next-app: 3 container_name: blog-portfolio 4 build: 5 context: . 6 dockerfile: Dockerfile 7 target: dev 8 ports: 9 - "3000:3000" 10 volumes: 11 - .:/app:cached 12 - /app/node_modules 13 working_dir: /app 14 stdin_open: true 15 tty: true 16 networks: 17 - react-network 18 environment: 19 - CHOKIDAR_USEPOLLING=true 20 - WATCHPACK_POLLING=true 21 - NEXTJS_IGNORE_ESLINT=1 22 command: ["pnpm", "dev", "--turbo"] 23 24networks: 25 react-network: 26 driver: bridge

Why This Setup?

  • Multi-Stage Builds: Separate stages for base, development, and production.

  • Tini for Signal Handling: Prevents zombie processes.

  • Docker Cache Optimization: Layer caching speeds up builds.

  • Docker Compose: Simplifies orchestration.

5. Build the Image

1docker build -t my-next-app .

6. Run the Container

1docker run -p 3000:3000 my-next-app

7. Use Docker Compose

1 2# Uses BuildKit for faster, optimized builds 3export DOCKER_BUILDKIT=1 4export COMPOSE_DOCKER_CLI_BUILD=1 5 6docker compose up --build

8. Create Helper Scripts

up

1#!/bin/bash 2docker compose up

down

1#!/bin/bash 2docker compose down

build

1#!/bin/bash 2docker compose build

Now you can run your docker commands like the following:

1./up 2./down 3./build

Troubleshooting

Here are some common issues and fixes:

  • Container immediately exits: Ensure CMD and ENTRYPOINT are correctly defined. Use tty: true and stdin_open: true in Compose for interactive shells.

  • File changes not reflected: Double-check volume mounting syntax and ensure you’re not accidentally overriding with node_modules.

  • Permission errors: Files created inside containers might be owned by root. Use user-specific UID/GID settings if needed.

  • App not accessible: Ensure port mapping (-p 3000:3000) is correct and app is listening on 0.0.0.0.

  • Memory issues: Docker may throttle memory. Check Docker Desktop settings or adjust mem_limit in docker-compose.yml.

Production Tips

  • Use NODE_ENV=production: This minimizes dependencies and ensures performance optimizations.

  • Use multi-stage builds: As shown above, separating build and run stages reduces image size.

  • Don’t mount volumes: In production, avoid volumes: to ensure a read-only, consistent image.

  • Use a process manager: If needed, consider using pm2 or tini (as shown) to manage signals and child processes.

  • Enable health checks: Add a healthcheck directive to ensure your container is running correctly.

  • Security: Scan images for vulnerabilities with tools like docker scan or Trivy.

Additional Resources

If you’re just getting started with Docker and prefer visual learning, this video is a great introduction:

Prefer reading documentation? The official Docker docs are comprehensive and beginner-friendly: Official Docker Documentation

Final Thoughts

Docker is a game changer for consistent, scalable development. This guide shows how to Dockerize a Next.js app from start to finish. Once set up, your dev and production workflows become more reliable and repeatable.

Get started today and level up your Next.js workflow with Docker! 🐳

Recent Articles

March 31st 2025

NextJS 👨🏽‍💻
How to Implement AI Features in a NextJS Blog

How to Implement AI Features in a NextJS Blog

AI is transforming online content interaction. This guide shows how to integrate AI features in a NextJS blog step-by-step guide

AuthorCesar UsecheDuration~10 min

March 28th 2025

Docker 🐋
Why Docker & How to Dockerize a NextJS App

Why Docker & How to Dockerize a NextJS App

Learn why Docker is essential for modern development and how to containerize a NextJS app with a step-by-step guide.

AuthorCesar UsecheDuration~5 min

March 25th 2025

FrondEnd 💻
The Importance of Web Accessibility

The Importance of Web Accessibility

Making websites accessible improves usability, SEO, and ensures inclusivity for all users, including those with disabilities.

AuthorCesar UsecheDuration~7 min