Containerizing Spring Boot Application with Jib
Tags: springboot, docker, jib, java
Published: 2020-12-08 19:47:29

In this post, we will learn about how to create Docker or <a title="OCI" href="https://opencontainers.org/">OCI</a> compliant images, without installing any Docker client and without using a Dockerfile, for a Spring Boot application.

We will be doing all of this with the help of Jib aka Java Image Builder.
<h3>What Is Jib?</h3>
<blockquote><em>Jib is a Java containerizer from Google that lets Java developers build containers using build tools like Maven and Gradle.</em></blockquote>
But that’s not all that is really interesting about Jib: you don’t need to know anything about installing Docker, maintaining Dockerfiles, etc.

As a developer, you only care about the artifact (jar, war, etc.) you will produce, and you don’t have to deal with any of the Docker nonsense (build/push, etc.).

<img class="alignnone wp-image-36706 size-medium" src="https://foojay.io/wp-content/uploads/2020/12/jib-700x443.png" alt="" width="700" height="443">

Wow, this is really powerful! But how?
<h3>How To Jib</h3>
With Jib, you can containerize your Java applications in no time by adding Maven or Gradle plugins to your pom.xml.or build.gradle file. It is that simple. However, in this post I will be covering Maven for demonstration purpose. Let’s get started, then.

We will be using Spring <a title="initializr" href="https://start.spring.io/">initializr</a> to generate a working Spring Boot project. Source code of our Spring Boot application is available <a title="here" href="https://github.com/yrashish/spring-boot-jib">here</a>, and it just prints a "Hello" message when the image is pushed via Jib and the image is run through Docker.

Once we are set up ready with an IDE, we can proceed with the next step.
<h3>Setting Up Maven</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="xml">&lt;plugin&gt;
   &lt;groupId&gt;com.google.cloud.tools&lt;/groupId&gt;
   &lt;artifactId&gt;jib-maven-plugin&lt;/artifactId&gt;
   &lt;version&gt;2.6.0&lt;/version&gt;
   &lt;configuration&gt;
      &lt;from&gt;
         &lt;image&gt;gcr.io/distroless/java:11&lt;/image&gt;
      &lt;/from&gt;
      &lt;to&gt;
         &lt;image&gt;registry.hub.docker.com/hiashish/spring-boot-jib-image&lt;/image&gt;
      &lt;/to&gt;
   &lt;/configuration&gt;
&lt;/plugin&gt;</pre>
For Maven, you can paste the above content in your pom.xml plugin section, and you are good to go. But I will try to explain <code>from</code> and <code>image</code> tags here.
<blockquote><strong>&lt;from&gt;</strong> Configures the base image to build your application on top of. <span style="font-size: inherit;">Typically you don’t need to provide the </span><code>from</code><span style="font-size: inherit;"> tag as, by default, it uses a distroless Java 8 image. However, I have used Java 11, so I have explicitly mentioned that here. Moreover, depending upon your use case, you may want to use a different base image.</span></blockquote>
<blockquote><strong>&lt;image&gt;</strong> This refers to the target image that will pushed to the container registry. <span style="font-size: inherit;">I have used the Docker registry, but you can use any cloud provider(ECS, GCR, ACR) container registry.</span></blockquote>
To use further options with the plugin, you can refer to the <a title="documentation" href="https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin">documentation</a>.
<h3>Setting Credentials For Registry</h3>
To push an image, we would need to add registry credentials to maven settings.xml. Since we are just doing a demo, it’s ok to provide credentials this way but avoid using it as it is not secure. You may want to secure credentials as mentioned <a title="here" href="https://maven.apache.org/guides/mini/guide-encryption.html">here</a>.
<pre class="EnlighterJSRAW" data-enlighter-language="xml">&lt;server&gt;
    &lt;id&gt;registry.hub.docker.com&lt;/id&gt;
    &lt;username&gt;username&lt;/username&gt;
    &lt;password&gt;password&lt;/password&gt;
&lt;/server&gt;<code class="language-xml"></code></pre>
<h3>Building An Image</h3>
To build an image, we can do it in the following ways.
<ol>
 	<li><strong>IDE. </strong>For example, in IntelliJ, you can go to maven view of your project, then go under Plugins&gt;jib, then right-click and run the maven build. You may want to create an IntelliJ run configuration that can run maven goals like clean, compile, etc., then push your image.<img class="size-full wp-image-36689" src="https://foojay.io/wp-content/uploads/2020/12/Screenshot-2020-12-29-at-12.10.08-AM.png" alt="Intellij screenshot" width="458" height="334"></li>
 	<li><strong>Using the command line. </strong>Just run the below command to build an image of your application. Make sure you have Maven installed first:
<pre class="EnlighterJSRAW" data-enlighter-language="xml">mvn compile jib:build</pre>
It will compile, build, and then push your application's image to the configured container registry.</li>
</ol>
Following is the output:
<pre class="EnlighterJSRAW" data-enlighter-language="generic">ashish@MacBook-Air springboot % mvn compile jib:build
[INFO] Scanning for projects…
[INFO]
[INFO] — — — — — — — — — — &lt; com.example:spring-boot-jib &gt; — — — — — — — — — — -
[INFO] Building springboot 0.0.1-SNAPSHOT
[INFO] — — — — — — — — — — — — — — — — [ jar ] — — — — — — — — — — — — — — — — -
[INFO]
[INFO] — — maven-resources-plugin:3.1.0:resources (default-resources) @ spring-boot-jib — -
[INFO] Using ‘UTF-8’ encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 0 resource
[INFO]
[INFO] — — maven-compiler-plugin:3.8.1:compile (default-compile) @ spring-boot-jib — -
[INFO] Nothing to compile — all classes are up to date
[INFO]
[INFO] — — jib-maven-plugin:2.6.0:build (default-cli) @ spring-boot-jib — -
[WARNING] ‘mainClass’ configured in ‘maven-jar-plugin’ is not a valid Java class: ${start-class}
[INFO]
[INFO] Containerizing application to registry.hub.docker.com/hiashish/spring-boot-jib-image…
[WARNING] Base image ‘gcr.io/distroless/java:11’ does not use a specific image digest — build may not be reproducible
[INFO] Using credentials from Maven settings file for registry.hub.docker.com/hiashish/spring-boot-jib-image
[INFO] Using base image with digest: sha256:b25c7a4f771209c2899b6c8a24fda89612b5e55200ab14aa10428f60fd5ef1d1
[INFO]
[INFO] Executing tasks:
[INFO]
[INFO] Executing tasks:
[INFO]
[INFO] Executing tasks:
[INFO] [======= ] 25.0% complete
[INFO]
[INFO] Executing tasks:
[INFO] [======= ] 25.0% complete
[INFO] &gt; pushing blob sha256:6508f436f385b3751366f90b6…
[INFO]
[INFO] Executing tasks:
[INFO] [======= ] 25.0% complete
[INFO] &gt; pushing blob sha256:6508f436f385b3751366f90b6…
[INFO] &gt; pushing blob sha256:c5e22041fc97b838b93a2e18d…
[INFO]
[INFO] Executing tasks:
[INFO] [======= ] 25.0% complete
[INFO] &gt; pushing blob sha256:6508f436f385b3751366f90b6…
[INFO] &gt; pushing blob sha256:c5e22041fc97b838b93a2e18d…
[INFO] &gt; pushing blob sha256:b25902383f9ee26808b68ca62…
[INFO]
[INFO] Executing tasks:
[INFO] [======= ] 25.0% complete
[INFO] &gt; pushing blob sha256:6508f436f385b3751366f90b6…
[INFO] &gt; pushing blob sha256:c5e22041fc97b838b93a2e18d…
[INFO] &gt; pushing blob sha256:b25902383f9ee26808b68ca62…
[INFO] &gt; checking base image layer sha256:31eb28996804…
[INFO]
[INFO] Executing tasks:
[INFO] [======== ] 27.8% complete
[INFO] &gt; pushing blob sha256:c5e22041fc97b838b93a2e18d…
[INFO] &gt; pushing blob sha256:b25902383f9ee26808b68ca62…
[INFO] &gt; checking base image layer sha256:31eb28996804…
[INFO]
[INFO] Executing tasks:
[INFO] [========= ] 30.6% complete
[INFO] &gt; pushing blob sha256:c5e22041fc97b838b93a2e18d…
[INFO] &gt; checking base image layer sha256:31eb28996804…
[INFO]
[INFO] Executing tasks:
[INFO] [========== ] 33.3% complete
[INFO] &gt; checking base image layer sha256:31eb28996804…
[INFO]
[INFO] Executing tasks:
[INFO] [=========== ] 35.0% complete
[INFO]
[INFO] Executing tasks:
[INFO]
[INFO]
[INFO]
[INFO] Container entrypoint set to [java, -cp, /app/resources:/app/classes:/app/libs/*, com.jib.example.spring.SpringbootApplication]
[INFO]
[INFO] Built and pushed image as registry.hub.docker.com/hiashish/spring-boot-jib-image
[INFO] Executing tasks:
[INFO] [=========================== ] 91.7% complete
[INFO] &gt; launching layer pushers
[INFO]
[INFO] — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
[INFO] BUILD SUCCESS
[INFO] — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
[INFO] Total time: 8.746 s
[INFO] Finished at: 2020–11–16T02:34:33+05:30
[INFO] — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —</pre>
<h3>Running An Image</h3>
We have successfully pushed the image (image name:spring-boot-jib-image) to a Docker registry. Now we can run the image using Docker.

<img class="size-medium wp-image-36688" src="https://foojay.io/wp-content/uploads/2020/12/Screenshot-2020-12-28-at-11.41.02-PM-700x147.png" alt="" width="700" height="147">

As you can see that our application is running inside a container. Now just run the curl command, and you can see that we got a hello message from our containerized spring-boot application.
<pre><code class="language-shell">curl localhost:8080/hello
Hello From Spring-Boot Jib</code></pre>
<h3>Quick Demo</h3>
{% youtube g2RaApg2zP8 %}
<h3>Conclusion</h3>
In this article, we have learned how we can containerize our Java applications without Docker. Additionally, with Jib, you can build images using Docker, but that’s not the X factor.

Other benefits of using Jib for your Java applications include that it's super easy to integrate with Java applications, producing faster builds, reproducible builds, community support, etc.

You can go through this <a title="link" href="https://www.google.com/amp/s/cloudblog.withgoogle.com/products/gcp/introducing-jib-build-java-docker-images-better/amp/">link</a> to know about Jib's benefits in detail.
<h4>Support me</h4>
If you like what you've just read, you can buy me a coffee! :-)
<a href="https://www.buymeacoffee.com/meashish" target="_blank" rel="noopener"><img style="height: 60px !important; width: 217px !important;" src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee"></a>
<h4>Further Reading</h4>
You can continue reading some of my previous <a href="https://ashishtechmill.com">articles</a>.