Docker | DevOps

Compare Image Size And Building Time Between Dockerfile, Buildpack, And Jib For A Multi-Module Project.

Noah Hsu
JavaToDev
Published in
4 min readJan 7, 2023

--

images downloads from https://github.com/GoogleContainerTools, https://github.com/paketo-buildpacks, and https://github.com/topics/docker

In this article, I will focus on four metrics

  1. time cost for building the first image
  2. time cost for building all 9 images
  3. image size
  4. shared image layer size

compare the difference between the following methods(source code link in the bottom of this article):

  1. Shell+Dockerfile: using a script to run gradle build and docker build for every server with a simple Dockerfile.
  2. Gradle Buildpack plugin: use the Buildpack plugin and run the gradle task, bootBuildImage.
  3. Gradle Jib plugin: use the Jib plugin with the default setting to run the gradle task, jibDockerBuild.

For each method we can divide into three scenarios:

  • the first build
  • the second build after some code change
  • the second build after some code change and clean artifacts(docker image and gradle build)

(code change: add a v2 API controller, service)

For a fair test, I’ll run three times for each scenario and take the average result. besides, I’ll clean the docker and by the following command before the next run and the third scenario above.

docker system prune -a
gradlew clean

Build Time Comparison

First, we compare the build time for both the first image and all images:

In this chart, we can be sure that the rank of building “single image” speed is Jib > Shell + Simple Dockerfile > Buildpack. Besides, the cache(gradle for Jib and build jar, Docker layer for other two methods) can really help in build time to speed up around 2 times.

In the second chart, we can find that the order for the speed of building “all images” changes to Shell + Simple Dockerfile > Jib >> Buildpack. In my opinion, both Jib and Buildpack are trying to optimize the image size and share layer by dividing the application jar into multiple image layers, so it takes more time while the simple Dockerfile only needs to copy the jar build by gradle into the image layer.

Image Size Comparison

Second, we compare the image size.

In this chart, we can find that the image size built by “shell + simple Dockerfile” is much bigger than others, and even grow almost twice when we store two versions of all images.

Then, the image size built by Buildpack and Jib is so close for both Single and all images in the first version, but Jib is outperform Buildpack when we build the second version.

Conclusion

For building image speed:

  1. Single image: Jib is the fastest.
  2. Multiple images: shell + Dockerfile is the fastest (Jib and Buildpack is slower due to the images layer strategy).
  3. The Buildpack plugin is always slower than others.

For Image size:

  1. Jib builds the smallest size image in all scenarios than others.
  2. The simple Dockerfile builds the fattest images and less shared layer between two versions of the application jar.

After this little experiment, I will say that Jib is a nice way to build images for your java application, although it may cost more time if our project is a multi-module project. Jib can provide a balance between image size, share layer size, and building time. Moreover, it’s a pure gradle/maven plugin, we don’t need a docker daemon at all, so we don’t need to install docker on the runner used in the CI process.

So, I will next do some research on how to tune the parameter and setting to make Jib run fast. Help it can make our CI process more efficient and save space for our image registry.

If you enjoyed this article, please follow me here on Medium for more stories about Spring boot and CI/CD process. Thanks for reading.

Reference

--

--

Noah Hsu
JavaToDev

Java ServerSide Engr🚀, Focusing on Spring, Toggle system, Kafka, Event Sourcing, and CI/CD. Support my work with a 🍺. https://www.buymeacoffee.com/swbhcjhtyvv