Docker Multistage Builds : Day 3 of 40daysofkubernetes

Docker Multistage Builds : Day 3 of 40daysofkubernetes

In my previous blog post, we learned how to dockerize an application by writing a Dockerfile to create an image. However, the resulting image was very large, which is not ideal for industry-level projects.

In this blog post, we will learn how to reduce the size of your Docker image by using multi-stage builds. This technique will help improve the efficiency and performance of your application.

We will follow the same steps, but we need to change our Dockerfile.

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
    

Resources I used ->

Multi-Stage builds