The Google blog post introducing Jib offers a really good definition:
An open-source Java containerizer from Google that lets Java developers build containers using the Java tools they know. Jib is a fast and simple container image builder that handles all the steps of packaging your application into a container image. It does not require you to write a Dockerfile or have docker installed, and it is directly integrated into Maven and Gradle—just add the plugin to your build and you’ll have your Java application containerized in no time.
Basically, it’s as stated. Jib helps us build a docker container without following the usual process and that only with a Maven or Gradle plugin. Here follows images to help you visualise the difference between the usual docker build flow against the jib build flow.
Docker build flow:
Jib build flow:
We can go from our code to an image pushed in our registry in one shot, without even having a running local docker daemon, that’s awesome right ?! And yes, you don’t actually need a running local docker daemon to push your image to a registry. Jib natively supports pushing to common registries such as Docker Hub, Google Container Registry (GCR), Amazon Elastic Container Registry (ECR) and Azure Container Registry (ACR) and for a custom one, just prefix the url to your image name.
Usage
Take a trip to the Jib Maven Plugin Quickstart or if you are using Gradle, go here instead. Read it in order to setup things like authentication to your registry. I will take this sample Spring Boot project available on Github as an example. After added this to the pom:
<plugins>
...
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>${jib.version}</version>
<configuration>
<from>
<image>openjdk:8u222-jre</image>
</from>
<to>
<image>docker.io/mlniang/jib-example:${project.version}</image>
</to>
<container>
<entrypoint>
<shell>sh</shell>
<option>-c</option>
<arg>chmod +x /entrypoint.sh && sync && /entrypoint.sh</arg>
</entrypoint>
<ports>
<port>8080</port>
</ports>
<environment>
<SPRING_OUTPUT_ANSI_ENABLED>ALWAYS</SPRING_OUTPUT_ANSI_ENABLED>
</environment>
<creationTime>USE_CURRENT_TIMESTAMP</creationTime>
</container>
</configuration>
</plugin>
...
</plugins>
The command mvn compile jib:build
built and pushed my image to docker hub. Assuming by now, you have read the documentation, here is a quick explanation of this configuration:
- Create and push the image
mlniang/jib-example:<pom_project_version>
to docker hub usingopenjdk:8u222-jre
as a base image. - In any container from our image, as the entrypoint, execute the script located in
src/main/jib/entrypoint.sh
which contains the java command for running our Spring Boot app in standalone mode. Jib will automatically add to the image any files in thesrc/main/jib
directory which will be available as the root of our containers. - Expose the port
8080
of any future container for access to our Spring Boot app. - Set the environment variable
SPRING_OUTPUT_ANSI_ENABLED
of any container . - Set the creation time of the container to be the current timestamp (it will use the UNIX EPOCH by default).
Note that your code need to be compiled before the jib:build
goal and the first run may take some time but next builds will be more faster due to the layer caching.
If you want to just build your image and not push it, you can use the jib:dockerBuild
goal instead. However, for this one, you must have a running docker daemon.
You can bind the execution of jib:build
or jib:dockerBuild
to an existing Maven lifecycle. If we want the jib:build goal to execute when we package our app, we will add to the plugin configuration:
...
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>${jib.version}</version>
<configuration>
...
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
...
Now, mvn clean package
is enough to get the job done.
One last thing: you can use command line parameters to override your configuration. One use case is when we want the current tag version of our image to be the latest. After my usual package command, I can go for:
$ mvn clean package -Djib.to.image=docker.io/mlniang/jib-example:latest
Without even modifying my pom.