698 words
3 minutes
Dockerizing a Node.js - Application with Multi-Stage Builds

Dockerizing a Node.js Application with Multi-Stage Builds#

In this blog post, we’ll walk through the process of dockerizing a Node.js application using multi-stage builds. We’ll also explore Docker best practices and the docker init command.

Step 1: Clone the Repository#

First, let’s clone a simple Node.js application from GitHub:

Terminal window
git clone https://github.com/yourusername/nodejs-express-app.git
cd nodejs-express-app

Step 2: Explore docker init#

Before we create our Dockerfile, let’s explore the docker init command:

Terminal window
docker init

This command initiates an interactive session to help set up a new Docker project. For our Node.js app, we might answer:

  • Application platform: Node.js
  • Application entrypoint: node src/index.js
  • Port to expose: 3000

Docker will generate a Dockerfile, .dockerignore, and compose.yaml based on these answers.

Step 3: Create a Multi-Stage Dockerfile#

While docker init provides a good starting point, let’s create a more optimized Dockerfile using multi-stage builds:

# Stage 1: Build
FROM node:18-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: Production
FROM node:18-alpine
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY --from=build /app/package*.json ./
RUN npm ci --only=production
EXPOSE 3000
CMD ["node", "dist/index.js"]

Let’s break down this Dockerfile:

  1. We use two stages: build and production.
  2. In the build stage, we install all dependencies and build the application.
  3. In the production stage, we only copy the built artifacts and production dependencies.

Step 4: Build the Docker Image#

Now, let’s build our Docker image:

Terminal window
docker build -t nodejs-express-app .

This command builds a Docker image tagged as nodejs-express-app using the Dockerfile in the current directory.

Step 5: Run the Docker Container#

With our image built, we can now run a container:

Terminal window
docker run -p 3000:3000 nodejs-express-app

This command runs a container from our image, mapping port 3000 in the container to port 3000 on our host machine.

Benefits of Multi-Stage Builds#

Multi-stage builds offer several advantages:

  1. Smaller final image: By only copying necessary files from the build stage, we reduce the final image size.
  2. Improved security: Build dependencies and sensitive data don’t make it into the final image.
  3. Faster builds: Subsequent builds can leverage Docker’s layer caching more effectively.
  4. Easier maintenance: Separating build and runtime environments makes the Dockerfile easier to understand and maintain.

Best Practices for Writing Dockerfiles#

After reviewing the Docker documentation on best practices, here are some key points:

  1. Use official base images: They’re maintained and typically more secure.
  2. Minimize the number of layers: Combine commands where it makes sense (e.g., using && in RUN instructions).
  3. Use .dockerignore: Exclude unnecessary files from the build context.
  4. Use specific tags: Instead of latest, use specific version tags for base images.
  5. Use multi-stage builds: As we’ve done, to optimize image size and build process.
  6. Order instructions from least to most frequently changing: This optimizes caching.
  7. Use environment variables: For values that might change between environments.

Conclusion#

We’ve successfully dockerized a Node.js application using multi-stage builds! Here’s a quick recap of the commands we used:

  • git clone: Clone the repository
  • docker init: Initialize a new Docker project
  • docker build: Build a Docker image
  • docker run: Run a Docker container

By following these steps and best practices, you can create efficient, secure, and maintainable Docker images for your applications.

You can find the complete code for this project, including the Dockerfile, in my GitHub repository: https://github.com/yourusername/nodejs-express-app

Happy Dockerizing!

Build Stage 1. Copy package.json 2. npm ci 3. Copy source code 4. npm run build Production Stage 1. Copy built artifacts 2. Copy package.json 3. npm ci --only=production 4. Set CMD
Dockerizing a Node.js - Application with Multi-Stage Builds
https://mranv.pages.dev/posts/dockerizing-nodejs-app-multistage-builds/
Author
Anubhav Gain
Published at
2024-09-22
License
CC BY-NC-SA 4.0