Tips to run Docker Build faster

Image taken from https://foxutech.com/how-to-build-a-docker-image-using-dockerfile/

Let’s assume we are containerising an Angular application & we created Dockerfile at project’s root directory

Lets build our Angular project first

After build, project directory looks like below

Lets build the Docker image now

The docker build command approximately took 53 seconds to run 😱

On side note, you can calculate time taken to run any command in Linux/Mac by appending the word time before your command

> time docker build -t my-img .

The nginx image we used for building our Docker image is just 20.6MB in size . Why is it taking 53 seconds to build such a small Docker image ?

The culprit here is the build context

Understanding Build Context

In docker build -t my-img . command, you could have noticed .(dot) at the end which implies

  • Dockerfile resides in the current directory
  • Build context is set in the current directory

Docker build command will first compress and create a tar file of everything inside Build Context’s directory. Then that tar file will be sent to the Docker Daemon for building Docker image

Since we kept Dockerfile in the project root directory, build command is creating tar file of entire root directory of the project (including node_modules folder 😱)

Thats why we are seeing Sending build context to Docker daemon 378.9MB in output, meaning 378.9 MB transferred to Docker daemon for building the docker image by the build command

Note, Docker Daemon could be running either in our local system or in remote server. If its in remote, we will be sending 378 MB data to Docker Daemon in remote server for every single build command

How to avoid this ?

Don’t create Dockerfile in project root directory ! Always create Dockerfile or docker-compose file inside Docker folder

Whats the catch with this solution ?

Dockerfile can only refer to files/folders available in its current or its subdirectories

E.g. — Angular/NodeJS Application

We need contents of dist folder to build our Docker image. The dist folder usually gets generated in root directory by ng build command

If we moved Dockerfile to Docker folder, we can’t refer dist folder from Dockerfile

How to fix this ?

Go to angular.json file & change the “outputPath”: “dist/my-app” to “outputPath”: “Docker/dist/my-app”

This will ensure the dist folder getting generated inside Docker folder all the time

After doing above step, Lets run docker build from inside Docker folder

Note :

  • Only 273.4kB sent to Docker daemon from Build Context
  • Build completed in just 1.079 seconds 🔥🔥🔥

E.g — Spring Boot Application

Consider a Spring Boot app with Dockerfile created in project root directory

Project structure looks like below

Let’s build the Docker image

Build command is sending nearly 81 MB tar file (including src, target & even .idea folder) to Docker daemon and entire build took approximately 12 seconds to run

Now let’s move the Dockerfile to Docker folder. Remember, we still need the JAR file from target folder to build Docker image

So lets configure the spring-boot-maven-plugin to create JAR file inside Docker folder instead of target folder

In pom.xml

Now mvn clean package will create EmpApp.jar file inside Docker folder

Lets run the docker build command again & see the results

Now Docker build only sends 40 MB (size of EmpApp.jar) to Docker Daemon & the entire build took only 4.49 seconds

Thats all folks !!!

Twitter @IamVickyAV

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store