Containerizing Spring Boot Application with Jib

Subscribe to my newsletter and never miss my upcoming articles

In this post, we will learn about how to create docker or OCI complaint images without installing any docker client or using Dockerfile for a Spring Boot application. We will be doing all of this with the help of Jib.

What Is Jib?

Jib is Java containerizer from Google that lets Java developers build containers using the build tools like Maven, Gradle etc.

But that’s not all that is really interesting about Jib because you don’t need to know anything about installing docker, maintaining Dockerfile, 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.).

Wow, this is really powerful! But how? Alt Text

How To Jib?

With Jib, you can containerize your Java applications in no time by adding Maven or Gradle plugin to your pom.xml.or build.gradle file. It is that simple. However, in this post, I will be covering Maven for demonstration purposes. Let’s get started then.

We will be using spring initializr to generate a working spring-boot project. Source code of our Spring Boot application is available here, and it just prints a Hello message when the image is pushed via Jib and the image is run through docker.

Once we have set up ready with IDE, we can proceed with the next step.

Setting Up Maven

<plugin>
   <groupId>com.google.cloud.tools</groupId>
   <artifactId>jib-maven-plugin</artifactId>
   <version>2.6.0</version>
   <configuration>
      <from>
         <image>gcr.io/distroless/java:11</image>
      </from>
      <to>
         <image>registry.hub.docker.com/hiashish/spring-boot-jib-image</image>
      </to>
   </configuration>
</plugin>

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 from and image tags here.

from

Configures the base image to build your application on top of.

Typically you don’t need to provide from tag as by default, it uses 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.

image

This refers to the target image that will be pushed to the container registry.

I have used the docker registry, but you can use any cloud provider(ECR, GCR, ACR) container registry.

To use further options with the plugin, you can refer to the documentation.

Setting Credentials For Registry

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 here.

<server>
    <id>registry.hub.docker.com</id>
    <username>username</username>
    <password>password</password>
</server>

Building an Image

To build an image, we can do it in the following ways.

  1. IDE

For example, in IntelliJ, you can go to maven view of your project, then go under Plugins>jib, select jib:build, 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. Intellij screenshot

2. Using the command line

Just run the below command to build an image of your application. Make sure you have maven installed.

mvn compile jib:build

It will compile, build, and then push your application's image to the configured container registry.

Following is the output.

mvn compile jib:build
[INFO] Scanning for projects…
[INFO]
[INFO] — — — — — — — — — — < com.example:spring-boot-jib > — — — — — — — — — — -
[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] > pushing blob sha256:6508f436f385b3751366f90b6…
[INFO]
[INFO] Executing tasks:
[INFO] [======= ] 25.0% complete
[INFO] > pushing blob sha256:6508f436f385b3751366f90b6…
[INFO] > pushing blob sha256:c5e22041fc97b838b93a2e18d…
[INFO]
[INFO] Executing tasks:
[INFO] [======= ] 25.0% complete
[INFO] > pushing blob sha256:6508f436f385b3751366f90b6…
[INFO] > pushing blob sha256:c5e22041fc97b838b93a2e18d…
[INFO] > pushing blob sha256:b25902383f9ee26808b68ca62…
[INFO]
[INFO] Executing tasks:
[INFO] [======= ] 25.0% complete
[INFO] > pushing blob sha256:6508f436f385b3751366f90b6…
[INFO] > pushing blob sha256:c5e22041fc97b838b93a2e18d…
[INFO] > pushing blob sha256:b25902383f9ee26808b68ca62…
[INFO] > checking base image layer sha256:31eb28996804…
[INFO]
[INFO] Executing tasks:
[INFO] [======== ] 27.8% complete
[INFO] > pushing blob sha256:c5e22041fc97b838b93a2e18d…
[INFO] > pushing blob sha256:b25902383f9ee26808b68ca62…
[INFO] > checking base image layer sha256:31eb28996804…
[INFO]
[INFO] Executing tasks:
[INFO] [========= ] 30.6% complete
[INFO] > pushing blob sha256:c5e22041fc97b838b93a2e18d…
[INFO] > checking base image layer sha256:31eb28996804…
[INFO]
[INFO] Executing tasks:
[INFO] [========== ] 33.3% complete
[INFO] > 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] > 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] — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

Running an Image

We have successfully pushed the image(image name:spring-boot-jib-image) to a docker registry. Now we can run the image using docker.

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.

curl localhost:8080/hello
Hello From Spring-Boot Jib

Quick Demo

Conclusion

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 super easy to integrate with Java applications, faster builds, reproducible builds, community support, etc. You can go through this link to know about Jib's benefits in detail.

Support me

If you like what you just read then you can buy me a coffee Buy Me A Coffee

Comments (8)

Senthilkumar's photo

Really Thanks Ashish for sharing about Jib!! Really its helpful!!

When i done the similar kind of setup in my machine and getting the below error when i execute mvn compile jib:build command. Can you please help me?

Error: D:\Senthil\Java\spring-jib\spring-jib>mvn compile jib:build [WARNING] [WARNING] Some problems were encountered while building the effective settings [WARNING] Unrecognised tag: 'server' (position: START_TAG seen ...<pluginGroups/>\r\n <server>... @7:15) @ C:\Users\tssen.m2\settings.xml, line 7, column 15 [WARNING] [INFO] Scanning for projects... [INFO] [INFO] -----------------------< com.example:spring-jib >----------------------- [INFO] Building spring-jib 0.0.1-SNAPSHOT [INFO] --------------------------------[ war ]--------------------------------- [INFO] [INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) @ spring-jib --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Using 'UTF-8' encoding to copy filtered properties files. [INFO] Copying 1 resource [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ spring-jib --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- jib-maven-plugin:2.7.1:build (default-cli) @ spring-jib --- [WARNING] mainClass, extraClasspath, jvmFlags, and expandClasspathDependencies are ignored for WAR projects [INFO] [INFO] Containerizing application to registry.hub.docker.com/hiashish/spring-boo..... [ERROR] I/O error for image [registry.hub.docker.com/hiashish/spring-boo..: [ERROR] java.net.SocketException [ERROR] Socket Closed [ERROR] I/O error for image [registry.hub.docker.com/hiashish/spring-boo..: [ERROR] java.net.SocketException [ERROR] Socket Closed [INFO] Executing tasks: [INFO] [=============== ] 50.0% complete [INFO] > scheduling building manifests [INFO] > launching layer pushers [INFO] > scheduling pushing container configurations [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 14.601 s [INFO] Finished at: 2021-04-06T14:21:34+05:30 [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal com.google.cloud.tools:jib-maven-plugin:2.7.. (default-cli) on project spring-jib: Build image failed, perhaps you should make sure your credentials for 'registry.hub.docker.com/hiashish/spring-boo..' are set up correctly. See github.com/GoogleContainerTools/jib/blob/ma.. for help: Unauthorized for registry.hub.docker.com/hiashish/spring-boo..: 401 Unauthorized [ERROR] HEAD registry.hub.docker.com/v2/hiashish/spring-.. [ERROR] -> [Help 1] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] cwiki.apache.org/confluence/display/MAVEN/M..

Settings.xml: <settings xmlns="maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="w3.org/2001/XMLSchema-instance" xsi:schemaLocation="maven.apache.org/SETTINGS/1.0.0 maven.apache.org/xsd/settings-1.0.0.xsd"> <localRepository/> <interactiveMode/> <offline/> <pluginGroups/> <server> <id>registry.hub.docker.com</id> <username>username</username> <password>password</password> </server> <mirrors/> <proxies/> <profiles/> <activeProfiles/> </settings>

Show +5 replies
Ashish Choudhary's photo

Senthilkumar I have never explicitly passed username and password while running jib:build. You can check the documentation for more details. I have not passed any credentials explicitly in the demo video, so it should pick up from the setttings.xml file.

Senthilkumar's photo

Hi Ashish,

All setup are done now when i try to execute docker run command using docker run -it --rm -p 8080:8080 senthil131720/demo getting below error. I have installed Docker in my machine. Please advice. Thanks again!

D:\Senthil\Java\spring-jib\spring-jib>docker run -it --rm -p 8080:8080 senthil131720/demo Error: -jar requires jar file specification Usage: java [options] <mainclass> [args...] (to execute a class) or java [options] -jar <jarfile> [args...] (to execute a jar file) or java [options] -m <module>[/<mainclass>] [args...] java [options] --module <module>[/<mainclass>] [args...] (to execute the main class in a module) or java [options] <sourcefile> [args] (to execute a single source-file program)