Day 3 of 40 days of Kubernetes Series : Multi Stage Docker Build

What is a Docker Multi-Stage Build? A Docker multi-stage build is a Dockerfile that uses multiple FROM statements to build a Docker image in stages. This can be used to reduce the image size, improve performance, and make the build process more efficient.

Why Use Docker Multi-Stage Builds? There are several reasons to use Docker multi-stage builds:

  • Reduce image size: By using multiple FROM statements, you can copy only the necessary files from each stage to the final image. This can significantly reduce the image size.

  • Improve performance: Smaller images are faster to download and run.

  • Make the build process more efficient: Multi-stage builds can help you organize your build process and make it easier to debug.

Get Started

  1. Clone a sample git repository using the below command or use your project for the demo:

      git clone https://github.com/piyushsachdeva/todoapp-docker.git
    
  2. cd into the todoapp-docker directory.

  3. Create a file named Dockerfile using the command below.

  4. Paste the following code into your Dockerfile.

      FROM node:18-alpine AS installer
      WORKDIR /app
      COPY package*.json ./
      RUN npm install 
      COPY . .
      RUN npm run build
      FROM nginx:latest AS deployer
      COPY --from=installer /app/build /usr/share/nginx/html
    

    Explanation of this code:

    Stage 1: Installer

    1. Specify Base Image for Installer Stage

      FROM node:18-alpine AS installer

      This line sets the base image to node:18-alpine, which is a lightweight version of Node.js 18. The AS installer part names this stage installer.

    2. Set Working Directory

      WORKDIR /app

      This sets the working directory inside the container to /app. All subsequent commands will be run within this directory.

    3. Copy Package Files

      COPY package*.json ./

      This copies package.json and package-lock.json (if it exists) from your local machine to the working directory (/app) inside the container.

    4. Install Dependencies

      RUN npm install

      This runs npm install to install all the dependencies listed in package.json. These dependencies are installed within the container.

    5. Copy Application Code

      Copy codeCOPY . .

      This copies the rest of your application code from your local machine to the container’s working directory (/app).

    6. Build the Application

      RUN npm run build

      This runs the build script defined in your package.json, typically creating a production-ready version of your application in a build directory.

Stage 2: Deployer

  1. Specify Base Image for Deployer Stage

    FROM nginx:latest AS deployer

    This sets the base image to nginx:latest, which is the latest version of the Nginx web server. The AS deployer part names this stage deployer.

  2. Copy Built Application to Nginx

    COPY --from=installer /app/build /usr/share/nginx/html

    This copies the build artifacts from the installer stage (specifically from /app/build) into the Nginx container’s web root directory (/usr/share/nginx/html). The --from=installer flag specifies that the source files should be taken from the installer stage.

We write our Dockerfile in two stages-

  • First Stage (installer):

    • Uses a Node.js image to install dependencies and build the application.

    • The build artifacts are created in the /app/build directory.

  • Second Stage (deployer):

    • Uses an Nginx image to serve the built application.

    • Copies the build artifacts from the installer stage into Nginx’s web root.

  1. Now build the Docker image with the following command:

      docker build -t imageName:tagname .
    
  2. Run the container by following command

      docker run -dp 3000:3000 imageName:tagname
    
  3. To enter in the container use this command

      docker exec -it containername sh
      or
      docker exec -it containerid sh
    

Conclusion

Docker multi-stage builds are a powerful tool that can help you create smaller, faster, and more efficient Docker images. By following the best practices outlined in this blog, you can get the most out of this technique.

References:

https://www.youtube.com/watch?v=ajetvJmBvFo&list=PLl4APkPHzsUUOkOv3i62UidrLmSB8DcGC&index=6

0
Subscribe to my newsletter

Read articles from Rahul Vadakkiniyil directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Rahul Vadakkiniyil
Rahul Vadakkiniyil