The Ops Community ⚙️

Leonardo Rodrigues de Oliveira
Leonardo Rodrigues de Oliveira

Posted on

Multi-Stage Dockerfiles, Why and How to Use Them

When building Docker images, it's often necessary to install build tools and dependencies to compile your application. However, these build tools and dependencies can take up a lot of space in your Docker image, which can make your image larger than necessary. To solve this problem, Docker introduced multi-stage builds.

Multi-stage builds allow you to use multiple FROM statements in a single Dockerfile. Each FROM statement begins a new build stage, allowing you to build and package different parts of your application in separate stages. This can result in smaller and more efficient Docker images.

Here's an example of a multi-stage Dockerfile for a Node.js application:

# Stage 1: Build the application
FROM node:14-alpine AS build

WORKDIR /app

COPY package.json package-lock.json ./
RUN npm install

COPY . .
RUN npm run build

# Stage 2: Serve the application
FROM node:14-alpine

WORKDIR /app

COPY --from=build /app/dist ./dist
COPY package.json package-lock.json ./
RUN npm install --production

CMD ["npm", "start"]

Enter fullscreen mode Exit fullscreen mode

Let's go over what this Dockerfile is doing. In the first stage, we're using the node:14-alpine base image to build the application. We set the working directory to /app, copy the package.json and package-lock.json files, and run npm install. Then, we copy the rest of the application files and run npm run build. This will compile the application into the /app/dist directory.

In the second stage, we're using the node:14-alpine base image again to serve the application. We set the working directory to /app, copy the compiled files from the previous stage using the --from flag, copy the package.json and package-lock.json files, and run npm install --production. Finally, we set the command to start the application using npm start.

When building this Dockerfile, Docker will first build the first stage, then use the compiled files in the second stage. This allows us to keep the build tools and dependencies in the first stage, and only include the compiled files and runtime dependencies in the second stage. The resulting Docker image will be smaller and more efficient.

To build this Dockerfile, run the following command in the same directory as the Dockerfile:

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

This will build the Docker image and tag it with the name my-node-app. You can then run the Docker image using the following command:

docker run -p 8080:8080 my-node-app
Enter fullscreen mode Exit fullscreen mode

This will start the Docker container and map port 8080 on the container to port 8080 on the host machine.

That's it! You now know how to create a multi-stage Dockerfile to build and package your applications more efficiently.


More Content

If this article helped you or someone you know and you want to know more of these useful tools or tips for your IaC needs, follow me on LinkedIn, here or on GitHub and don't miss my updates!

Top comments (0)