If you don’t want to call docker directly in your build, there is quite a rich set of plugins for Maven and Gradle that can do that work for you. Here are just a few.

That builds an anonymous docker image. We can tag it with docker on the command line now, or use Maven configuration to set it as the repository . Example (without changing the pom.xml ):

For really basic usage it will work out of the box with no extra configuration:

The Spotify Maven Plugin is a popular choice. It requires the application developer to write a Dockerfile and then runs docker for you, just as if you were doing it on the command line. There are some configuration options for the docker image tag and other stuff, but it keeps the docker knowledge in your application concentrated in a Dockerfile , which many people like.

In this example we have chosen to unpack the Spring Boot fat jar in a specific location in the build directory, which is the root for the docker build. Then the multi-layer (not multi-stage) Dockerfile from above will work.

First you need to import the plugin into your build.gradle :

The Palantir Gradle Plugin works with a Dockerfile and it also is able to generate a Dockerfile for you, and then it runs docker as if you were running it on the command line.

Jib Maven and Gradle Plugins

Google has an open source tool called Jib that is relatively new, but quite interesting for a number of reasons. Probably the most interesting thing is that you don’t need docker to run it - it builds the image using the same standard output as you get from docker build but doesn’t use docker unless you ask it to - so it works in environments where docker is not installed (not uncommon in build servers). You also don’t need a Dockerfile (it would be ignored anyway), or anything in your pom.xml to get an image built in Maven (Gradle would require you to at least install the plugin in build.gradle ).

Another interesting feature of Jib is that it is opinionated about layers, and it optimizes them in a slightly different way than the multi-layer Dockerfile created above. Just like in the fat jar, Jib separates local application resources from dependencies, but it goes a step further and also puts snapshot dependencies into a separate layer, since they are more likely to change. There are configuration options for customizing the layout further.

Example with Maven (without changing the pom.xml ):

$ mvn com.google.cloud.tools:jib-maven-plugin:build -Dimage=myorg/myapp

To run the above command you will need to have permission to push to Dockerhub under the myorg repository prefix. If you have authenticated with docker on the command line, that will work from your local ~/.docker configuration. You can also set up a Maven "server" authentication in your ~/.m2/settings.xml (the id of the repository ios significant):

settings.xml

<server> <id>registry.hub.docker.com</id> <username>myorg</username> <password>...</password> </server>

There are other options, e.g. you can build locally against a docker daemon (like running docker on the command line), using the dockerBuild goal instead of build . Other container registries are also supported and for each one you will need to set up local authentication via docker or Maven settings.

The gradle plugin has similar features, once you have it in your build.gradle , e.g.

build.gradle

plugins { ... id 'com.google.cloud.tools.jib' version '0.9.11' }

or in the older style used in the Getting Started Guides:

build.gradle

buildscript { repositories { maven { url "https://plugins.gradle.org/m2/" } mavenCentral() } dependencies { classpath('org.springframework.boot:spring-boot-gradle-plugin:2.0.5.RELEASE') classpath('com.google.cloud.tools.jib:com.google.cloud.tools.jib.gradle.plugin:0.9.11') } }

and then you can build an image with

$ ./gradlew jib --image=myorg/myapp