Skip to main content
  1. Posts/

Accelerating Java Application Container Image Builds with Google JIB

·367 words·2 mins
Bang~
Author
Bang~
Nose to the grindstone

JIB Overview
#

Jib is Google’s newly open-sourced tool for building Docker images for Java applications. It can generate images and push them to a registry directly via Gradle or Maven, without requiring a Dockerfile or any other plugins. Jib supports packaging resource files and classes into separate layers, significantly improving image build speed.

Why Use JIB?
#

Docker’s Client-Server Architecture Has Limitations: Building images incurs additional overhead as it copies all files from the Dockerfile’s context directory to the Docker Daemon, including unnecessary ones. We encountered a real production issue where building a Node.js application was slow due to numerous cached residual files in the context directory being copied.

Traditional SpringBoot Packaging Underutilizes Layer Caching: Even a one-line code change results in the entire BootJar application layer being cached. This imposes overhead during both image download and push operations.

Configuration
#

  1. Add the following configuration to your build.gradle file:
plugins {
    id 'java'
    id 'com.google.cloud.tools.jib' version '3.1.4' // Apply the Jib Gradle plugin
}

def date = new Date()

jib {
    from {
        image = 'openjdk:8-jdk-alpine' // Specify base image
    }
    to {
        image = 'registry.cn-shanghai.aliyuncs.com/xxxx/projectName:' + date.getTime() // Specify target private registry address
        auth { // Registry credentials
            username = 'xxx'
            password = 'xxx'
        }
    }
    container {
        jvmFlags = ['-Duser.timezone=GMT+08'] // Specify JVM arguments
        mainClass = 'xxxx.xxxx.XxxxApplication' // Main application class
        args = ['test'] // Arguments passed to the main method
        ports = ['8080'] // Exposed container ports (equivalent to Dockerfile's EXPOSE)
    }
}

Building the Image
#

Execute the following command in the project root directory:

./gradlew clean jib or ./gradlew clean jibDockerBuild (Builds using the local Docker daemon)

Upon successful build, you will see:

Built and pushed image as registry.cn-shanghai.aliyuncs.com/XXX/XXX:1631811887971
Executing tasks:
[============================  ] 91.7% complete
> launching layer pushers

Notice that when using openjdk:8-jdk-alpine as the base image, the resulting SpringBoot application image is just over 100MB—nearly 50% smaller compared to previous images typically ranging from 200-300MB.

But what’s with the “created on 51 years ago”..?

As indicated in https://github.com/GoogleContainerTools/jib/issues/3030, we can add the following configuration to build.gradle:

jib {
    ....
    container {
        ....
        creationTime = 'USE_CURRENT_TIMESTAMP'
    }
}

However, note that this sacrifices reproducibility. For details, please refer to: https://github.com/GoogleContainerTools/jib/blob/master/docs/faq.md#why-is-my-image-created-48-years-ago