Build Docker and OCI images for Java applications using google Jib

Whenever we talk about Docker maven plugins for java applications, we automatically think of fabric8io maven plugin, which is, honestly, a great plugin. But today, I'm going to talk about a new discovery: Jib, a Maven plugin for building Docker and OCI images for Java applications.

Why Jib ?!

The project page answer this with 3 important goals:

  • Fast: Jib claims that it can deploy the changes faster. I can confirm that, the first push will take some time, but the follow updates will be pushed (a lot) faster, since Jib separates the application into multiple layers, splitting dependencies from classes, eliminating the wait for Docker to rebuild the entire Java application. It'll just deploy the layers that changed.

  • Reproducible: Rebuilding the container image with the same contents always generates the same image.

  • Native: Jib Reduce CLI dependencies. We can build Docker images from within Maven and push them to any registry of choice.

Showtime!

I've tried Jib for a few weeks now, and I'm really impressed. To use it, you'll need to add the plugin to your pom.xml

<plugin>
  <groupId>com.google.cloud.tools</groupId>
  <artifactId>jib-maven-plugin</artifactId>
  <version>${jib.version}</version>
  <configuration>
    <registry>${myregistry}</registry>
    <repository>${myimage}</repository>
  </configuration>
</plugin>

This is a very minimal configuration, that configures the registry and repository to push the built image. We can extend Jib configuration with more options for customizing the image build:

<configuration>
  <from>openjdk:10-jre</from>
  <registry>${myregistry}</registry>
  <repository>${myimage}</repository>
  <tag>${app-tag}</tag>
  <jvmFlags>
    <jvmFlag>-Xms1g</jvmFlag>
  </jvmFlags>
  <mainClass>mypackage.MyApp</mainClass>
  <enableReproducibleBuilds>true</enableReproducibleBuilds>
  <imageFormat>Docker</imageFormat>
</configuration>

The configuration above specifies that the image should be built from a base of openjdk:10-jre, pushed to ${myregistry}/${myimage}:${app-tag}. The image runs with the option -Xms1g -cp app/libs/*:app/resources:app/classes and has as main class mypackage.MyApp. For the complete list of options, check the project page.

Authentication Methods

Jib supports 2 main authentication methods to secure Pushing/pulling operations from private registries: using Docker credential helpers or defined credentials in Maven settings.

I prefer the combination of Maven setting with Maven password encryption to secure the credentials of my private registries. This look something like this

<settings>
  ...
  <servers>
    ...
    <server>
      <id>localhost:5000</id>
      <username>aboullaite</username>
      <password>{COQLCE6DU6GtcS5P=}</password>
    </server>
  </servers>
</settings>

More details on this can be found here.

Jib is an interesting and promising project. It still has some limitation and some improvement to brings, but I highly recommend giving it a try ;)