JIB is a great tool to create Docker/OCI images in plain Java. Since a few versions, it got some extension API and the official JIB extension - used as a demo - enables to filter the files added to layer.

The most common use case is to build a distribution - Apache Karaf, Apache TomEE, Wildfly, .... - and want to add it to a docker image. You have a phase creating the distribution in a folder then you add this folder through JIB...but you need to add the "build" module jar to the docker image (in classpath/ folder) which is fully useless most of the time.

To solve that, you can now configure the filter extension and request to drop the classpath/ folder:

  <plugin> <!-- 1 -->
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
      <skipIfEmpty>false</skipIfEmpty>
    </configuration>
  </plugin>
  <plugin>
    <groupId>com.google.cloud.tools</groupId>
    <artifactId>jib-maven-plugin</artifactId>
    <executions>
      <execution>
        <id>build</id>
        <phase>none</phase> <!-- 2 -->
        <configuration>
          <containerizingMode>packaged</containerizingMode> <!-- 3 -->
          <extraDirectories>
            <paths> <!-- 4 -->
              <path>${project.build.directory}/distribution</path>
            </paths>
          </extraDirectories>
          <from>
            <image>...</image>
          </from>
          <to>
            <image>...</image>
          </to>
          <container>
            <appRoot>${image.workdir}</appRoot>
            <workingDirectory>${image.workdir}</workingDirectory>
            <!-- ... -->
          </container>
          <pluginExtensions>
            <pluginExtension> <!-- 5 -->
              <implementation>com.google.cloud.tools.jib.maven.extension.layerfilter.JibLayerFilterExtension
              </implementation>
              <configuration implementation="com.google.cloud.tools.jib.maven.extension.layerfilter.Configuration">
                <filters>
                  <filter> <!-- 6 -->
                    <glob>${image.workdir}/classpath/*</glob>
                  </filter>
                </filters>
              </configuration>
            </pluginExtension>
          </pluginExtensions>
        </configuration>
      </execution>
    </executions>
    <dependencies>
      <dependency> <!-- 7 -->
        <groupId>com.google.cloud.tools</groupId>
        <artifactId>jib-layer-filter-extension-maven</artifactId>
        <version>0.1.0</version>
      </dependency>
    </dependencies>
  </plugin>
  1. We enable maven to build the jar of current module even if empty (if relevant),
  2. We don't bind the docker creation in the main build - if you want to do so, you can replace none by package for example,
  3. Thanks to 1., we can configure jib in packaged mode and avoid it to fail to add module files because the module is empty,
  4. We add the distribution folder we prepared with another plugin (karaf:assemblytomee:build),
  5. We add the filter extension, this looks like a simple IoC configuration (thanks Maven/plexus ;)),
  6. We configure the filter extension to remove the classpath/ directory - note it matches container root folder configuration,
  7. Finally, for the filter extension to work we must add the extension to the plugin dependency.

Now, we just need to run the following command to get our "folder based" docker image containing exactly what we want:

mvn package jib:dockerBuild@build

Indeed, this has the drawback to require to know what is in the docker image, whereas JIB seems to not require it, but as soon as you build a custom assembly/distribution, it must be the case anyway so at the end, it just makes JIB compatible with distribution based images and not only opiniated flat classpath images :).

 

From the same author:

In the same category: