Building using Maven
There are a number of Maven plugins available for building and deploying Docker images. We’re going to use Fabric8.
Git hash based version numbers
There are a number of Maven plugins available for interacting with git, we recommend the Maven git commit id plugin. This plugin will allow us to make certain git based properties available to the build, which we can then use to compute the version number.
To use it, add this plugin to the build section of your parent POM:
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<version>4.0.0</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>revision</goal>
</goals>
</execution>
</executions>
<configuration>
<dateFormat>yyyyMMdd-HHmmss</dateFormat>
<generateGitPropertiesFile>false</generateGitPropertiesFile>
</configuration>
</plugin>
Now, in the properties section of the parent POM, create a version number based on the commit time and id. Using the commit time is useful because it makes it possible to sort tags chronologically:
<properties>
<version.number>${git.commit.time}-${git.commit.id.abbrev}</version.number>
</properties>
The version number will only change when you create a new git commit. If you are not using the latest
tag in your deployment spec, then make sure when you update your project and want to redeploy, that you commit your changes first so you get a new version number, and to ensure that version number correlates to what is in the git repository at that commit hash.
Configuring the Fabric8 Docker plugin
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.34.1</version>
<configuration>
<images>
<image>
<name>%a</name>
<build>
<from>adoptopenjdk:11-jre-hotspot</from>
<tags>
<tag>latest</tag>
<tag>${version.number}</tag>
</tags>
<entryPoint>
<exec>
<arg>java</arg>
<arg>-cp</arg>
<arg>/maven/*</arg>
<arg>akka.cluster.bootstrap.demo.DemoApp</arg>
</exec>
</entryPoint>
<assembly>
<descriptorRef>artifact-with-dependencies</descriptorRef>
</assembly>
</build>
</image>
</images>
</configuration>
<executions>
<execution>
<id>build-docker-image</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
There are two things to pay careful attention to here.
- The base image we’re using is
adoptopenjdk:11-jre-hotspot
. You can use any Docker image that provides a JRE, this is the one we recommend for open source users of Kubernetes. docker:build
is added to thepackage
phase do that the Docker image is built when runningmvn package
- Versions
latest
and${version.number}
are tagged - Artifact with dependencies is set for the assembly. Meaning your application and its dependencies are added to
/maven
in the Docker image
Building the Docker image
To build and publish the image run the following. The Docker username and registry are taken from system properties.
Note that the registry to push to must include the username, for example -Ddocker.registry=docker.io/youruser
.
Security information (i.e. user and password) can be specified in multiple ways as described in section docker-maven-plugin authentication.
mvn -Ddocker.username=<user> -Ddocker.registry=<registry>/<user> package docker:push