1. Introduction

Gradle plugin for managing Docker images and containers using via its remote API. The heavy lifting of communicating with the Docker remote API is handled by the Docker Java library. Please refer to the library’s documentation for more information on the supported Docker’s client API and Docker server version.

This plugin requires Gradle >= 5.2 to work properly.

1.1. Benefits

There are various benefits for using this plugin:

  1. Seamless integration with the build tool Gradle and its DSL.

  2. Handles complicated communication logic between Docker client and daemon under the covers.

  3. Simplifies the definition of complex workflows.

  4. Minimizes build script setup logic by providing sensible conventions for different use cases.

1.2. Limitations

The functionality of the plugin does not cover all possible use cases. Be aware of the following limitations:

  • A task type may not provide all possible options for the underlying Docker operation. Open an issue if you feel like it should be supported.

  • You cannot build multi-container applications via Docker Compose. The Avast Docker Compose plugin has proven to be a capable alternative.

  • Managing a Docker Swarm and/or Stack is not supported.

1.4. Provided Plugins

The binary distribution is available on the Gradle plugin portal, Bintray’s JCenter and Maven Central. It contains the following plugins:

Plugin Id Automatically applies Type Description

com.bmuschko.docker-remote-api

-

DockerRemoteApiPlugin

Provides custom tasks for interacting with Docker via its remote API.

com.bmuschko.docker-java-application

com.bmuschko.docker-remote-api

DockerJavaApplicationPlugin

Creates and pushes a Docker image for a Java application.

com.bmuschko.docker-spring-boot-application

com.bmuschko.docker-remote-api

DockerSpringBootApplicationPlugin

Creates and pushes a Docker image for a Spring Boot application.

Which plugin you chose in your project entirely depends on the use case you want to fulfill. Refer to the relevant portions of the user guide that describe the purpose and usage of each plugin in more detail.

1.5. Getting Started

The plugin can be applied with the buildscript syntax or the plugin DSL. Let’s say you’d want to go with the plugin that provides the plain Docker operations for managing Docker images and containers. See the Gradle user guide for more information on applying plugins.

1.5.1. Applying the Plugin Using the buildscript Syntax

Groovy
buildscript {
    repositories {
        gradlePluginPortal()
    }
    dependencies {
        classpath 'com.bmuschko:gradle-docker-plugin:6.7.0'
    }
}

apply plugin: 'com.bmuschko.docker-remote-api'
Kotlin
buildscript {
    repositories {
        gradlePluginPortal()
    }
    dependencies {
        classpath("com.bmuschko:gradle-docker-plugin:6.7.0")
    }
}

apply(plugin = "com.bmuschko.docker-remote-api")

1.5.2. Applying the Plugin Using the Plugin DSL

Groovy
plugins {
    id 'com.bmuschko.docker-remote-api' version '6.7.0'
}
Kotlin
plugins {
    id("com.bmuschko.docker-remote-api") version "6.7.0"
}

1.5.3. Applying the Plugin From a Script Plugin

Applying the plugin from a script plugin requires the use of the fully-qualified class name due to a bug in Gradle core. Be aware that the plugin DSL cannot be used to apply a binary plugin from a script plugin.

When used with the Kotlin DSL, it is recommended to move your implementation into the buildSrc project.
gradle/docker.gradle
buildscript {
    repositories {
        gradlePluginPortal()
    }
    dependencies {
        classpath 'com.bmuschko:gradle-docker-plugin:6.7.0'
    }
}

apply plugin: com.bmuschko.gradle.docker.DockerRemoteApiPlugin
build.gradle
apply from: 'gradle/docker.gradle'

2. Remote API Plugin

The plugin com.bmuschko.docker-remote-api allows for interacting with Docker via its remote API. If no additional configuration has been provided by the build script, the plugin will try to resolve and use the credentials for registry authentication available from previous login operations (usually in $HOME/.docker/config.json). You can model any workflow imaginable by creating enhanced task of the custom task provided by the plugin.

2.1. Usage

Groovy
plugins {
    id 'com.bmuschko.docker-remote-api' version '6.7.0'
}

// Import task types
import com.bmuschko.gradle.docker.tasks.image.*

// Use task types
task buildMyAppImage(type: DockerBuildImage) {
    inputDir = file('docker/myapp')
    images.add('test/myapp:latest')
}
Kotlin
plugins {
    id("com.bmuschko.docker-remote-api") version "6.7.0"
}

// Import task types
import com.bmuschko.gradle.docker.tasks.image.*

// Use task types
tasks.create("buildMyAppImage", DockerBuildImage::class) {
    inputDir.set(file("docker/myapp"))
    images.add("test/myapp:latest")
}

The plugin automatically resolves the Docker Java library with the pre-configured version under the covers. The only configuration you will have to provide in your build script is the repository hosting the library and its transitive dependencies. One repository that hosts them all is Maven Central.

Groovy
repositories {
    mavenCentral()
}
Kotlin
repositories {
    mavenCentral()
}

2.2. Extension

The plugin defines an extension with the namespace docker. The following properties can be configured:

Property name Type Default value Description

url

Property<String>

unix:///var/run/docker.sock (Unix), tcp://127.0.0.1:2375 (Windows)

The server URL to connect to via Docker’s remote API.

certPath

DirectoryProperty

Value of environment variable DOCKER_CERT_PATH if set

The path to certificates for communicating with Docker over SSL.

apiVersion

Property<String>

null

The remote API version. For most cases this can be left null.

Image pull or push operations against the public Docker Hub registry or a private registry may require authentication. By default, existing credentials are read from $HOME/.docker/config.json and reused for authentication purposes. You can overwrite those credentials with the help of the registryCredentials closure. The credentials provided in the extension automatically become available to all custom tasks that implement the interface RegistryCredentialsAware.

Property name Type Default value Description

url

Property<String>

https://index.docker.io/v1/

The registry URL.

username

Property<String>

null

The registry username.

password

Property<String>

null

The registry password.

email

Property<String>

null

The registry email address.

2.2.1. Working With a TLS-enabled Docker Instance

Starting with Docker version 1.3, TLS is enabled by default. Please consult the Docker documentation "Protect the Docker daemon socket" to set up your certificate. The following example demonstrates how to configure the plugin to use those certificates. Additionally, this code snippet shows how to set the user credentials.

Groovy
docker {
    url = 'https://192.168.59.103:2376'
    certPath = new File(System.properties['user.home'], '.boot2docker/certs/boot2docker-vm')

    registryCredentials {
        url = 'https://index.docker.io/v1/'
        username = 'bmuschko'
        password = 'pwd'
        email = 'benjamin.muschko@gmail.com'
    }
}
Kotlin
docker {
    url.set("https://192.168.59.103:2376")
    certPath.set(File(System.getProperty("user.home"), ".boot2docker/certs/boot2docker-vm"))

    registryCredentials {
        url.set("https://index.docker.io/v1/")
        username.set("bmuschko")
        password.set("pwd")
        email.set("benjamin.muschko@gmail.com")
    }
}

2.2.2. Working With Google Cloud And Using a Key File

Groovy
docker {
    registryCredentials {
        url = 'https://gcr.io'
        username = '_json_key'
        password = file('keyfile.json').text
    }
}
Kotlin
docker {
    registryCredentials {
        url.set("https://gcr.io")
        username.set("_json_key")
        password.set(file("keyfile.json").readText())
    }
}

2.2.3. Working With a Docker Instance Without TLS

The following example assumes that you disabled TLS on your Docker instance. You can do so by setting DOCKER_TLS=no in the file /var/lib/boot2docker/profile.

Groovy
docker {
    url = 'tcp://192.168.59.103:2375'
}
Kotlin
docker {
    url.set("tcp://192.168.59.103:2375")
}

On Unix the Docker daemon listens by default on unix:///var/run/docker.sock.

On Windows the Docker daemon listens by default on npipe:////./pipe/docker_engine if this exists. We fall back to tcp://127.0.0.1:2375 where the pipe does not exist.

2.3. Custom task types

2.3.1. Misc

The plugin provides the following general-purpose custom task types:

Type Description

DockerOperation

Passes the raw docker-java client to the onNext closure if it’s defined.

DockerInfo

Displays system-wide information.

DockerVersion

Show the docker version information.

2.3.2. Images

The plugin provides the following custom task types for managing images:

Type Description

Dockerfile

Creates a Dockerfile based on the provided instructions.

DockerBuildImage

Builds an image from a Dockerfile.

DockerCommitImage

Creates a new image from a container’s changes.

DockerInspectImage

Returns low-level information on the image.

DockerListImages

Lists images in registry.

DockerPullImage

Pulls an image from the registry.

DockerPushImage

Pushes an image to a registry.

DockerRemoveImage

Removes an image from the filesystem.

DockerTagImage

Tags an image in registry.

DockerSaveImage

Saves an image to file.

DockerLoadImage

Loads an image from file.

2.3.3. Containers

The plugin provides the following custom task types for managing containers:

Type Description

DockerCopyFileToContainer

Copies a path from the host into the container.

DockerCopyFileFromContainer

Copies a path from the container as a tar file on to the host.

DockerCreateContainer

Creates a container.

DockerInspectContainer

Returns low-level information on the container.

DockerKillContainer

Kills the container for a given id.

DockerRemoveContainer

Removes the container for a given id from the filesystem.

DockerRenameContainer

Rename a container.

DockerRestartContainer

Restarts the container for a given id.

DockerStartContainer

Starts the container for a given id.

DockerStopContainer

Stops the container for a given id.

DockerWaitContainer

Blocks until container for a given id stops.

DockerLogsContainer

Copies the container output to the Gradle process standard out/err.

DockerExecContainer

Executes a command within a running container.

DockerInspectExecContainer

Inspects task executed inside container with DockerExecContainer command.

2.3.4. Networks

The plugin provides the following custom task types for managing networks:

Type Description

DockerCreateNetwork

Creates a network.

DockerInspectNetwork

Returns low-level information on the network.

DockerRemoveNetwork

Removes the network.

2.3.5. Extras

deprecated

The plugin provides the following additional tasks:

Type Description

DockerExecStopContainer

Shut down container with cmd, polling for it to enter a non-running state, and if that does not succeed in time issue stop request.

DockerLivenessContainer

Polls an arbitrary containers logs for a message indicating liveness.

DockerWaitHealthyContainer

Blocks until the container for a given id becomes healthy.

2.4. Reactive Streams

As needed, we will implement reactive methods as described in reactive-streams. We implement these here as optional closures for all tasks. Currently the only supported methods are onError, onNext, onComplete. Various examples on how to use these can be found in our reactive tests.

2.4.1. Reacting to an Error

The onError closure is passed the exception that is thrown for you to handle. If you silently ignore we will not throw the exception behind the scenes. The below example is a common use-case that arises when someone wants to remove a container whether it exists or not but does not want to fail hard.

Groovy
task removeContainer1(type: DockerRemoveContainer) {
    targetContainerId 'container-that-does-not-exist'
    onError { exception ->
        // Ignore exception if container does not exist otherwise throw it
        if (!exception.message.contains('No such container'))
            throw exception
    }
}
Kotlin
tasks.create("removeContainer1", DockerRemoveContainer::class) {
    targetContainerId("container-that-does-not-exist")
    onError {
        // Ignore exception if container does not exist otherwise throw it
        if (!this.message!!.contains("No such container"))
            throw this
    }
}

2.4.2. Reacting to Data Returned by an Operation

The onNext closure is passed the next iterative response upon execution. For all other tasks we simply hand you back the object that is given to us by docker-java which is a pojo representation of the json handed back by docker. Thus, and much like the onError closure, all delegation is now in your control. Any properties/values expected to be set will not be done unless you do them.

Iterative tasks are things like DockerBuildImage, DockerLogsContainer, DockerListImages. These tasks have output which can be iterated over. The example below demonstrates how we iterate over each log message passing that to the closure for the user to work on.

Groovy
task logContainer(type: DockerLogsContainer) {
    targetContainerId 'container-that-does-exist'
    follow = true
    tailAll = true
    onNext { message ->
        // Each log message from the container will be passed as it's made available
        logger.quiet message.toString()
    }
}
Kotlin
tasks.create("logContainer", DockerLogsContainer::class) {
    targetContainerId("container-that-does-not-exist")
    follow.set(true)
    tailAll.set(true)
    onNext {
        // Each log message from the container will be passed as it's made available
        logger.quiet(this.toString())
    }
}

2.4.3. Reacting to the Completion of an Operation

The onComplete closure is not passed anything upon execution. It works in the same fashion that doLast does but is instead part of this task and thus executes before doLast does. This closure executes only upon success. The below example demonstrates how this works.

Groovy
task removeContainer2(type: DockerRemoveContainer) {
    targetContainerId 'container-that-does-exist'
    onComplete {
        println 'Executes first'
    }
    doLast {
        println 'Executes second'
    }
}
Kotlin
tasks.create("removeContainer2", DockerRemoveContainer::class) {
    targetContainerId("container-that-does-exist")
    onComplete {
        println("Executes first")
    }
    doLast {
        println("Executes second")
    }
}

2.5. Examples

The following usage examples demonstrate code for common use cases. More scenarios can be found in the functional tests.

2.5.1. Modifying Instructions of a Dockerfile Task

Sometimes do you do not have any control over the creation of a Dockerfile task. For example the Docker Java Application Plugin already adds a Dockerfile task with a set of sensible instructions. You can still modify those instructions if needed. Let’s say you are dealing with the following Dockerfile definition.

Groovy
tasks.create('createDockerfile', Dockerfile) {
    from('openjdk:jre-alpine')
    copyFile('my-app-1.0.jar', '/app/my-app-1.0.jar')
    entryPoint('java')
    defaultCommand('-jar', '/app/my-app-1.0.jar')
    exposePort(8080)
}
Kotlin
tasks.create("createDockerfile", Dockerfile::class) {
    from("openjdk:jre-alpine")
    copyFile("my-app-1.0.jar", "/app/my-app-1.0.jar")
    entryPoint("java")
    defaultCommand("-jar", "/app/my-app-1.0.jar")
    exposePort(8080)
}

Now, you may prefer a different base image than the one added by default. The listing below demonstrates how to find it the FROM instruction and replace it with a different one.

Groovy
createDockerfile {
    List<Instruction> originalInstructions = new ArrayList<Instruction>(instructions.get())
    int fromInstructionIndex = originalInstructions
            .findIndexOf { it.keyword == FromInstruction.KEYWORD }
    originalInstructions.remove(fromInstructionIndex)
    FromInstruction baseImage = new FromInstruction(new From('openjdk:8-alpine'))
    originalInstructions.add(0, baseImage)
    instructions.set(originalInstructions)
}
Kotlin
tasks {
    "createDockerfile"(Dockerfile::class) {
        val originalInstructions = instructions.get().toMutableList()
        val fromInstructionIndex = originalInstructions
                .indexOfFirst { item -> item.keyword == FromInstruction.KEYWORD }
        originalInstructions.removeAt(fromInstructionIndex)
        val baseImage = FromInstruction(From("openjdk:8-alpine"))
        originalInstructions.add(0, baseImage)
        instructions.set(originalInstructions)
    }
}

You can also add new instructions at a specific position in the existing list of instructions. For example you may want to add a HEALTHCHECK to the end of the list.

Groovy
createDockerfile {
    instruction 'HEALTHCHECK CMD wget --quiet --tries=1 --spider http://localhost:8080/actuator/health || exit 1'
}
Kotlin
tasks {
    "createDockerfile"(Dockerfile::class) {
        instruction("HEALTHCHECK CMD wget --quiet --tries=1 --spider http://localhost:8080/actuator/health || exit 1")
    }
}

2.5.2. Creating a Dockerfile And Building an Image

A Dockerfile can be created by the Dockerfile custom tasks. The Dockerfile instructions need to be declare in the correct order.

Groovy
plugins {
    id 'com.bmuschko.docker-remote-api' version '6.7.0'
}

import com.bmuschko.gradle.docker.tasks.image.Dockerfile
import com.bmuschko.gradle.docker.tasks.image.DockerBuildImage

task createDockerfile(type: Dockerfile) {
    from 'ubuntu:12.04'
    label(['maintainer': 'Benjamin Muschko "benjamin.muschko@gmail.com"'])
}

task buildImage(type: DockerBuildImage) {
    dependsOn createDockerfile
    images.add('bmuschko/myimage:latest')
}
Kotlin
plugins {
    id("com.bmuschko.docker-remote-api") version "6.7.0"
}

import com.bmuschko.gradle.docker.tasks.image.Dockerfile
import com.bmuschko.gradle.docker.tasks.image.DockerBuildImage

val createDockerfile by tasks.creating(Dockerfile::class) {
    from("ubuntu:12.04")
    label(mapOf("maintainer" to "Benjamin Muschko 'benjamin.muschko@gmail.com'"))
}

tasks.create("buildImage", DockerBuildImage::class) {
    dependsOn(createDockerfile)
    images.add("bmuschko/myimage:latest")
}

2.5.3. Executing Functional Tests Against a Running Container

The following example code demonstrates how to build a Docker image from a Dockerfile, starts up a container for this image and exercises functional tests against the running container. At the end of this operation, the container is stopped.

Groovy
plugins {
    id 'com.bmuschko.docker-remote-api' version '6.7.0'
}

import com.bmuschko.gradle.docker.tasks.container.*
import com.bmuschko.gradle.docker.tasks.image.*

task buildMyAppImage(type: DockerBuildImage) {
    inputDir = file('docker/myapp')
    images.add('test/myapp:latest')
}

task createMyAppContainer(type: DockerCreateContainer) {
    dependsOn buildMyAppImage
    targetImageId buildMyAppImage.getImageId()
    hostConfig.portBindings = ['8080:8080']
    hostConfig.autoRemove = true
}

task startMyAppContainer(type: DockerStartContainer) {
    dependsOn createMyAppContainer
    targetContainerId createMyAppContainer.getContainerId()
}

task stopMyAppContainer(type: DockerStopContainer) {
    targetContainerId createMyAppContainer.getContainerId()
}

task functionalTestMyApp(type: Test) {
    dependsOn startMyAppContainer
    finalizedBy stopMyAppContainer
}
Kotlin
plugins {
    id("com.bmuschko.docker-remote-api") version "6.7.0"
}

import com.bmuschko.gradle.docker.tasks.container.*
import com.bmuschko.gradle.docker.tasks.image.*

val buildMyAppImage by tasks.creating(DockerBuildImage::class) {
    inputDir.set(file("docker/myapp"))
    images.add("test/myapp:latest")
}

val createMyAppContainer by tasks.creating(DockerCreateContainer::class) {
    dependsOn(buildMyAppImage)
    targetImageId(buildMyAppImage.getImageId())
    hostConfig.portBindings.set(listOf("8080:8080"))
    hostConfig.autoRemove.set(true)
}

val startMyAppContainer by tasks.creating(DockerStartContainer::class) {
    dependsOn(createMyAppContainer)
    targetContainerId(createMyAppContainer.getContainerId())
}

val stopMyAppContainer by tasks.creating(DockerStopContainer::class) {
    targetContainerId(createMyAppContainer.getContainerId())
}

tasks.create("functionalTestMyApp", Test::class) {
    dependsOn(startMyAppContainer)
    finalizedBy(stopMyAppContainer)
}

2.5.4. Linking With Other Containers

In many situations your container does not start without dependencies like database. In that case you may wish using traditional linking:

Groovy
plugins {
    id 'com.bmuschko.docker-remote-api' version '6.7.0'
}

import com.bmuschko.gradle.docker.tasks.container.*
import com.bmuschko.gradle.docker.tasks.image.*

task buildMyAppImage(type: DockerBuildImage) {
    inputDir = file('docker/myapp')
    images.add('test/myapp')
}

task createDBContainer(type: DockerCreateContainer) {
    targetImageId 'postgres:latest'
    containerName = 'docker_auto'
    hostConfig.autoRemove = true
}

task createMyAppContainer(type: DockerCreateContainer) {
    dependsOn buildMyAppImage, createDBContainer
    targetImageId buildMyAppImage.getImageId()
    hostConfig.portBindings = ['8080:8080']
    hostConfig.autoRemove = true
    hostConfig.links = ["docker_auto:database"]

    // If you use Systemd in containers you should also add lines. #320
    hostConfig.binds = ['/sys/fs/cgroup': '/sys/fs/cgroup']
    tty = true
}

task startMyAppContainer(type: DockerStartContainer) {
    dependsOn createMyAppContainer
    targetContainerId createMyAppContainer.getContainerId()
}

task stopMyAppContainer(type: DockerStopContainer) {
    targetContainerId createMyAppContainer.getContainerId()
}

task functionalTestMyApp(type: Test) {
    dependsOn startMyAppContainer
    finalizedBy stopMyAppContainer
}
Kotlin
plugins {
    id("com.bmuschko.docker-remote-api") version "6.7.0"
}

import com.bmuschko.gradle.docker.tasks.container.*
import com.bmuschko.gradle.docker.tasks.image.*

val buildMyAppImage by tasks.creating(DockerBuildImage::class) {
    inputDir.set(file("docker/myapp"))
    images.add("test/myapp")
}

val createDBContainer by tasks.creating(DockerCreateContainer::class) {
    targetImageId("postgres:latest")
    containerName.set("docker_auto")
    hostConfig.autoRemove.set(true)
}

val createMyAppContainer by tasks.creating(DockerCreateContainer::class) {
    dependsOn(buildMyAppImage, createDBContainer)
    targetImageId(buildMyAppImage.getImageId())
    hostConfig.portBindings.set(listOf("8080:8080"))
    hostConfig.autoRemove.set(true)
    hostConfig.links.set(listOf("docker_auto:database"))

    // If you use Systemd in containers you should also add lines. #320
    hostConfig.binds.set(mapOf("/sys/fs/cgroup" to "/sys/fs/cgroup"))
    tty.set(true)
}

val startMyAppContainer by tasks.creating(DockerStartContainer::class) {
    dependsOn(createMyAppContainer)
    targetContainerId(createMyAppContainer.getContainerId())
}

val stopMyAppContainer by tasks.creating(DockerStopContainer::class) {
    targetContainerId(createMyAppContainer.getContainerId())
}

tasks.create("functionalTestMyApp", Test::class) {
    dependsOn(startMyAppContainer)
    finalizedBy(stopMyAppContainer)
}

2.5.5. Implementing Custom Docker Client Handling

The plugin provides an opinionated set of custom tasks for the most common Docker operations. Sometime the situation may arise that you want to have full control over what you want to call on the Docker client. To do so you can implement your own custom task that extends from AbstractDockerRemoteApiTask. The following example shows how to implement such a custom task:

Groovy
class DockerImageIdForName extends AbstractDockerRemoteApiTask {
    @Input
    final Property<String> filteredImageName = project.objects.property(String)

    @Internal
    final Property<String> imageId = project.objects.property(String)

    DockerImageIdForName() {
        onNext({ image ->
            imageId.set(image.id)
        })
    }

    @Override
    void runRemoteCommand() {
        def images = dockerClient.listImagesCmd()
            .withImageNameFilter(filteredImageName.get())
            .exec()

        for(image in images) {
            nextHandler.execute(image)
        }
    }
}
Kotlin
open class DockerImageIdForName : AbstractDockerRemoteApiTask {
    @Input
    val filteredImageName : Property<String> = project.objects.property(String::class)

    @Internal
    val imageId : Property<String> = project.objects.property(String::class)

    constructor() {
        onNext(Action {
            this.withGroovyBuilder {
                imageId.set(getProperty("id") as String)
            }
        })
    }

    override fun runRemoteCommand() {
        val images = getDockerClient().listImagesCmd()
            .withImageNameFilter(filteredImageName.get())
            .exec()

        for(image in images) {
            nextHandler.execute(image)
        }
    }
}

To use the custom task, simply create a task by type.

Groovy
task imageIdForName(type: DockerImageIdForName) {
    filteredImageName = 'alpine:3.4'
}

task printImageId {
    dependsOn imageIdForName
    doLast {
        logger.quiet "Resolved image ID ${imageIdForName.imageId.get()} for name ${imageIdForName.filteredImageName.get()}"
    }
}
Kotlin
val imageIdForName by tasks.creating(DockerImageIdForName::class) {
    filteredImageName.set("alpine:3.4")
}

val printImageId by tasks.creating {
    dependsOn(imageIdForName)
    doLast {
        logger.quiet("Resolved image ID ${imageIdForName.imageId.get()} for name ${imageIdForName.filteredImageName.get()}")
    }
}

3. Java Application Plugin

The plugin com.bmuschko.docker-java-application is a highly opinionated plugin for projects applying the Java plugin. Under the hood the plugin preconfigures tasks for creating and pushing Docker images for your Java application. The default configuration is tweakable via an exposed extension.

3.1. Usage

Groovy
plugins {
    id 'java'
    id 'com.bmuschko.docker-java-application' version '6.7.0'
}
Kotlin
plugins {
    java
    id("com.bmuschko.docker-java-application") version "6.7.0"
}

3.2. Extension

The plugin defines an extension with the namespace javaApplication as a child of the docker namespace. By default, the main class will be configured automatically by looking for a class with a public static void main(String[]) method available in the classpath of the main source set.

The following properties can be configured:

Property name Type Default value Description

baseImage

Property<String>

openjdk:jre-alpine

The Docker base image used for Java application.

maintainer

Property<String>

Value of system property user.name

The maintainer of the image.

ports

ListProperty<Integer>

[8080]

The Docker image exposed ports.

images

SetProperty<String>

[<project.group>/<applicationName>:<project.version>]

The images used for the build and push operation.

jvmArgs

ListProperty<String>

[]

The JVM arguments passed to the java command.

mainClassName

Property<String>

A unique main class name discovered by scanning the classpath

The main class name to use for starting the application. Setting an explicit value for this option is useful if your source code contains multiple main class files.

Groovy
docker {
    javaApplication {
        baseImage = 'dockerfile/java:openjdk-7-jre'
        maintainer = 'Benjamin Muschko "benjamin.muschko@gmail.com"'
        ports = [9090, 5701]
        images = ['jettyapp:1.115', 'jettyapp:latest']
        jvmArgs = ['-Xms256m', '-Xmx2048m']
    }
}
Kotlin
docker {
    javaApplication {
        baseImage.set("dockerfile/java:openjdk-7-jre")
        maintainer.set("Benjamin Muschko 'benjamin.muschko@gmail.com'")
        ports.set(listOf(9090, 5701))
        images.set(setOf("jettyapp:1.115", "jettyapp:latest"))
        jvmArgs.set(listOf("-Xms256m", "-Xmx2048m"))
    }
}

3.3. Tasks

The plugin provides a set of tasks for your project and preconfigures them with sensible defaults.

Task name Depends On Type Description

dockerSyncBuildContext

classes

TaskProvider<Sync>

Copies the application files to a temporary directory for image creation.

dockerCreateDockerfile

dockerSyncBuildContext

TaskProvider<Dockerfile>

Creates the Docker image for the Java application.

dockerBuildImage

dockerCreateDockerfile

TaskProvider<DockerBuildImage>

Builds the Docker image for the Java application.

dockerPushImage

dockerBuildImage

TaskProvider<DockerPushImage>

Pushes created Docker image to the repository.

3.4. Examples

The following usage examples demonstrate code for common use cases. More scenarios can be found in the functional tests.

3.4.1. Using the Plugin for an Application Run on Jetty

Groovy
plugins {
    id 'java'
    id 'com.bmuschko.docker-java-application' version '6.7.0'
}

version = '1.0'
sourceCompatibility = 1.7

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.eclipse.jetty.aggregate:jetty-all:9.4.29.v20200521'
}

docker {
    javaApplication {
        maintainer = 'Jon Doe "jon.doe@gmail.com"'
    }
}
Kotlin
plugins {
    java
    id("com.bmuschko.docker-java-application") version "6.7.0"
}

version = "1.0"

java {
    sourceCompatibility = JavaVersion.VERSION_1_7
    targetCompatibility = JavaVersion.VERSION_1_7
}

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.eclipse.jetty.aggregate:jetty-all:9.4.29.v20200521")
}

docker {
    javaApplication {
        maintainer.set("Jon Doe 'jon.doe@gmail.com'")
    }
}

3.4.2. Additional Instructions in Dockerfile

You can add additional instructions to the dockerfile using dockerDistTar and Dockerfile task DSL:

Groovy
dockerCreateDockerfile {
    instruction 'RUN ls -la'
    environmentVariable 'JAVA_OPTS', '-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap'
}
Kotlin
tasks.named<Dockerfile>("dockerCreateDockerfile") {
    instruction("RUN ls -la")
    environmentVariable("JAVA_OPTS", "-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap")
}

Or you can use form

Groovy
dockerCreateDockerfile.instructionsFromTemplate file('Dockerfile.tmpl')
Kotlin
tasks.named<Dockerfile>("dockerCreateDockerfile") {
    instructionsFromTemplate(file("Dockerfile.tmpl"))
}

4. Spring Boot Application Plugin

The plugin com.bmuschko.docker-spring-boot-application is a highly opinionated plugin for projects applying the Spring Boot plugin. Under the hood the plugin preconfigures tasks for creating and pushing Docker images for your Spring Boot application. The default configuration is tweakable via an exposed extension. The plugin reacts to either the java or war plugin.

The plugin only supports projects that use a 2.x version of the Spring Boot plugin.

4.1. Usage

Groovy
plugins {
    id 'java'
    id 'org.springframework.boot' version '2.0.3.RELEASE'
    id 'com.bmuschko.docker-spring-boot-application' version '6.7.0'
}
Kotlin
plugins {
    java
    id("org.springframework.boot") version "2.0.3.RELEASE"
    id("com.bmuschko.docker-spring-boot-application") version "6.7.0"
}

4.2. Extension

The plugin defines an extension with the namespace springBootApplication as a child of the docker namespace. By default, the main class will be configured automatically by looking for a class with a public static void main(String[]) method available in the classpath of the main source set. The main class needs to use the org.springframework.boot.autoconfigure.SpringBootApplication annotation to be discoverable.

The following properties can be configured:

Property name Type Default value Description

baseImage

Property<String>

openjdk:jre-alpine

The Docker base image used for the Spring Boot application.

maintainer

Property<String>

Value of system property user.name

The maintainer of the image.

ports

ListProperty<Integer>

[8080]

The Docker image exposed ports.

images

SetProperty<String>

[<project.group>/<applicationName>:<project.version>]

The images used for the build and push operation.

jvmArgs

ListProperty<String>

[]

The JVM arguments passed to the java command.

mainClassName

Property<String>

A unique main class name discovered by scanning the classpath

The main class name to use for starting the application. Setting an explicit value for this option is useful if your source code contains multiple main class files.

Groovy
docker {
    springBootApplication {
        baseImage = 'openjdk:8-alpine'
        ports = [9090, 8080]
        images = ['awesome-spring-boot:1.115', 'awesome-spring-boot:latest']
        jvmArgs = ['-Dspring.profiles.active=production', '-Xmx2048m']
    }
}
Kotlin
docker {
    springBootApplication {
        baseImage.set("openjdk:8-alpine")
        ports.set(listOf(9090, 8080))
        images.set(setOf("awesome-spring-boot:1.115", "awesome-spring-boot:latest"))
        jvmArgs.set(listOf("-Dspring.profiles.active=production", "-Xmx2048m"))
    }
}

4.3. Tasks

The plugin provides a set of tasks for your project and preconfigures them with sensible defaults.

Task name Depends On Type Description

dockerSyncBuildContext

classes

TaskProvider<Sync>

Copies the application files to a temporary directory for image creation.

dockerCreateDockerfile

dockerSyncBuildContext

TaskProvider<Dockerfile>

Creates the Docker image for the Spring Boot application.

dockerBuildImage

dockerCreateDockerfile

TaskProvider<DockerBuildImage>

Builds the Docker image for the Spring Boot application.

dockerPushImage

dockerBuildImage

TaskProvider<DockerPushImage>

Pushes created Docker image to the repository.

4.4. Examples

The following usage examples demonstrate code for common use cases. More scenarios can be found in the functional tests.

4.4.1. Using the Plugin For an Application Run on Tomcat

The Spring Boot archive can be created as executable JAR or WAR file. If you are target environment is a Servlet Container or Application Server, the WAR file is likely the better option. To generate a WAR file, simply apply the war plugin and declare the appropriate container-related dependencies to run the application locally.

Groovy
plugins {
    id 'war'
    id 'org.springframework.boot' version '2.0.3.RELEASE'
    id 'io.spring.dependency-management' version '1.0.5.RELEASE'
    id 'com.bmuschko.docker-spring-boot-application' version '6.7.0'
}

version = '1.0'
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8

repositories {
    jcenter()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
    providedRuntime 'org.apache.tomcat.embed:tomcat-embed-jasper'
}

docker {
    springBootApplication {
        baseImage = 'openjdk:8-alpine'
    }
}
Kotlin
plugins {
    war
    id("org.springframework.boot") version "2.0.3.RELEASE"
    id("io.spring.dependency-management") version "1.0.5.RELEASE"
    id("com.bmuschko.docker-spring-boot-application") version "6.7.0"
}

version = "1.0"

java {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
}

repositories {
    jcenter()
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web")
    providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
    providedRuntime("org.apache.tomcat.embed:tomcat-embed-jasper")
}

docker {
    springBootApplication {
        baseImage.set("openjdk:8-alpine")
    }
}

4.4.2. Providing Container Build-Time and Runtime Parameters

It’s common practice to provide JVM parameters to a Spring Boot application running in a container. For example, you might want to provide memory parameters or set a specific Spring profile. There’s a two ways to achieve this. Each of them serve different use cases.

You may want to provide JVM parameters when you build the image with a Dockerfile. That’s likely the case if you don’t want to change the parameters later when running the image in a container. You can provide a list of JVM parameters that should be baked into image with the extension property jvmArgs.

Hard-coding a JVM parameter may not be the right solution to your problem. There are situations when you want to provide runtime behavior when starting the container. A typical example is a Spring profile that needs to be enabled depending on the environment you want to run.

If you are running the image with Docker, then you can just provide pre-built environment variables known to Spring Boot. Below, we are running an application with the prod profile.

$ docker run -e "SPRING_PROFILES_ACTIVE=prod" -p 8080:8080 -t my-spring-boot-app:1.2.3

You can achieve the same behavior in Kubernetes by defining an environment variable in your Pod or Deployment spec. The example below demonstrates the use of a Deployment.

deployment.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
  name: my-spring-boot-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-spring-boot-app
  template:
    metadata:
      labels:
        app: my-spring-boot-app
    spec:
      containers:
        - name: my-spring-boot-app
          image: my-spring-boot-app:1.2.3
          env:
          - name: SPRING_PROFILES_ACTIVE
            value: prod

5. About This Project

5.2. Contributing

Over the years, the plugin has tremendously grown in popularity. Contributions from the community are very welcome. Have a look at the contribution guidelines to get started.

5.3. Development

5.3.1. Executing the Plugin’s Test Suite With Custom Configuration

It is required to install and run Docker Community Edition (CE) on the machine running tests. Please refer to the installation manual for more information. The default setup can be configured with the help of the properties shown in the table below:

Description System/Project Property Environment Variable Default Value

Docker server URL

dockerServerUrl

DOCKER_HOST

unix:///var/run/docker.sock

Docker cert path

dockerCertPath

DOCKER_CERT_PATH

null

Docker private registry URL

dockerPrivateRegistryUrl

DOCKER_REGISTRY_HOST

http://localhost:5000

The following usage examples demonstrates running functional tests against the a Docker instance:

$ ./gradlew functionalTest

OR

$ ./gradlew functionalTest -PdockerServerUrl=unix:///var/run/docker.sock

OR

$ ./gradlew functionalTest -DdockerServerUrl=unix:///var/run/docker.sock

OR

$ export DOCKER_HOST=unix:///var/run/docker.sock && ./gradlew functionalTest

OR

$ ./gradlew functionalTest -PdockerServerUrl=http://192.168.59.103:2376

5.4. Release Process

This section describes the release process designed and implemented for this project. Its main purpose is to explain to developers and maintainers how to prepare and release a new version of the binaries and the documentation.

5.4.1. Tools

The release process uses some external libraries and services described in detail below.

gradle-git

The gradle-git plugin is used to automatically determine the project version. org.ajoberstar.release-opinion is applied in the main build.gradle and configured in ReleasePlugin.kt. Please refer to the plugin documentation for more details.

gradle-git-publish

The gradle-git-publish Gradle plugin is used to publish the documentation to gh-pages branch. It is applied and configured in the DocumentationPlugin.kt file.

GitHub Actions

GitHub Actions service is used as our current CI/CD server. Build and deploy jobs are configured in the .github/workflows directory. Please refer its documentation for more details.

Bintray’s JCenter

Bintray’s JCenter service is used to publish plugin versions. The Bintray plugin uploads artifacts to a remote repository. The plugin configuration can be found in the PublishingPlugin.kt file.

5.4.2. Workflow

The release process is automated to some extent. The following steps describe the workflow.

  1. Developer updates RELEASE_NOTES.md with new planned version.

  2. Developer commits all changes in local working copy.

  3. Developer triggers new version release using the following command: ./gradlew release -Prelease.stage=final -Prelease.scope=[SCOPE] where [SCOPE] can be one of major, minor or patch, and determines which part of the version string <major>.<minor>.<patch> will be incremented.

  4. Gradle executes a build on developer’s machine which calculates new version string, creates new tag with it and pushes to the origin.

  5. When Gradle build is finished, developer’s work is done and the rest of the release process is automated.

  6. After push to the origin, GitHub Actions detects new tag and triggers a build.

  7. Executes a release stage if the commit also points to a Git tag.

  8. This stage assembles plugin binaries (with new version) and uploads them to Bintray (credentials are stored as encrypted secrets in GitHub). Furthermore, the API docs and the user guide are published to gh-pages branch (the access token is stored as secure variable).

6. Change Log

v6.7.0 (January 10, 2021)

  • Turn on RegistryAuthLocator for Windows - PR 974

  • Handle missing ServerURL from auth helper response - PR 959

  • Add support for health check in DockerCreateContainer custom task - PR 978

  • Deprecate extra tasks - PR 981

  • Remove Netty exec factory support - PR 963

v6.6.1 (July 29, 2020)

  • Mapping of DSL property images should propagate down to build and push task in convention plugins - PR 956

v6.6.0 (July 16, 2020)

  • Use configuration avoidance API in convention plugins - PR 940

  • Configured registry credentials in build script should take precedence over Docker credential helper - PR 945

v6.5.0 (July 3, 2020)

  • Default to Docker Hub when no registry is explicitly given - PR 942

  • Upgrade of Docker Java library to version 3.2.5 and default to communication transport to Apache HttpClient 5 - PR 942

v6.4.0 (March 23, 2020)

  • Keep the network name and network ID separate in DockerCreateNetwork - PR 920

  • Upgrade ASM dependency to Java 13/14-compatible version - PR 929

v6.3.0 (March 14, 2020)

  • Retrieve all known credentials for DockerBuildImage custom task - PR 913

  • Add support for setting custom workingDir in DockerExecContainer task - PR 927

v6.2.0 (March 10, 2020)

  • Upgrade Docker Java to next minor version - PR 925

  • Expose property for providing extra hosts - PR 926

v6.1.4 (February 23, 2020)

  • Nested property FileInstruction.getFile() renders warning as it doesn’t provide input or output annotation - Issue 919

v6.1.3 (January 26, 2020)

  • Credentials helper JSON output parsing falls back to default if it cannot be read properly - PR 909

v6.1.2 (January 14, 2020)

  • Decode base64 auth header - PR 902

v6.1.1 (December 12, 2019)

  • Add debug logging in Docker configuration parsing - PR 898

v6.1.0 (December 12, 2019)

  • Allow configuring the main class name for convention plugins - PR 892

  • Do not parse config file if it doesn’t exist - Issue 887

v6.0.0 (November 16, 2019)

  • Breaking Change! Multi-tag support for push operation and convention plugins - PR 867

  • Breaking Change! Renamed property tags to images for extensions DockerJavaApplication and DockerSpringBootApplication.

  • Breaking Change! Renamed property tag to image for custom tasks DockerBuildImage, DockerCommitImage, DockerPullImage, DockerSaveImage, DockerListImages,DockerCreateContainer.

  • Breaking Change! Removal of method DockerPullImage.getImageId(). Use DockerPullImage.getImage() instead.

  • Breaking Change! Host-related configuration properties in DockerCreateContainer have been moved to nested property for better maintainability - PR 873

  • Add properties ipcMode and sysctls to DockerCreateContainer - PR 862

  • Gradle 6.0 compatibility fixes - PR 869

  • Improve DSL for configuring registry credentials for custom tasks - PR 879

  • Plugin resolves and uses Docker credential helper - PR 865

  • Upgrade of Docker Java library to version 3.1.5

v5.3.0 (October 30, 2019)

  • Expose project-prop/sys-prop/env-var to optionally use netty-exec-cmd-factory - PR 876

v5.2.0 (October 5, 2019)

  • Potentially Breaking Change! Remove duplicated code in convention plugins - PR 864

  • Restore compatibility with Gradle 5.1 as runtime version - Issue 866

v5.1.0 (September 18, 2019)

  • Potentially Breaking Change! Remove remaining use of Application Plugin in convention plugins - PR 852

v5.0.0 (August 13, 2019)

  • Breaking Change! Remove exec/cmd hooks in Docker application plugin - PR 806

  • Breaking Change! API cleanup of Dockerfile task - PR 812

  • Breaking Change! Removed ItemJoiner from public API - PR 836

  • Respect symlinks in build context - Issue 837

v4.10.0 (June 12, 2019)

  • Expose target property for BuildImageTask - PR 813

  • Remove final from DockerBuildImage.labels property - PR 823

  • Always set imageId within DockerBuildImage on success - PR 819

v4.9.0 (May 25, 2019)

  • Avoid memory leakage by replacing addShutdownHook with Gradle.buildFinished - PR 810

  • DockerBuildImage will print whole lines by collecting output and waiting for newline - PR 799

  • DockerBuildImage reinstated ImageId output file and check in Docker registry - PR 807

v4.8.1 (May 11, 2019)

  • Introduce maintainer property to extension of Spring Boot application plugin - Issue 779

  • Breaking Change! Removed RepositoriesFallbackPlugin that was applied automatically - Issue 794

  • Breaking Change! The Docker client in AbstractDockerRemoteApiTask is not inject into the method runRemoteCommand anymore - Issue 802

v4.8.0 (April 22, 2019)

  • Expose extension property for configuring JVM arguments - PR 790

v4.7.1 (April 13, 2019)

v4.7.0 (April 9, 2019)

  • Tasks created by convention plugins should assign a task group - Issue 768

  • Main class detection should work with a Kotlin-based application - Issue 766

  • Fix gradle 5.x deprecation warnings - Issue 782

  • Bump docker-java to 3.1.2 - Issue 787

v4.6.2 (March 9, 2019)

  • Add shaded JAF dependency to simplify usage of plugin with Java 11 - Issue 764

v4.6.1 (March 6, 2019)

  • Fix setting binds in DockerCreateContainer task - Issue 758

v4.6.0 (March 3, 2019)

  • Breaking Change! Plugin declares and uses Docker Java as runtime library - PR 751

  • Breaking Change! Custom task DockerClient has been renamed to DockerOperation to avoid conflicting Docker Java class name

  • Shade plugin dependencies except Docker Java - PR 755

v4.5.0 (February 19, 2019)

  • Dockerfile.FileInstruction does not use flags if Dockerfile.File is passed in using a Provider - PR 753

  • Inline main class finder and avoid explicit dependency on Spring Boot - PR 752

v4.4.1 (February 5, 2019)

  • Cannot set publishAll property without error - PR 742

v4.4.0 (January 31, 2019)

  • Breaking Change! Define image with more fine-grained image layers - PR 736

  • Bump docker-java-shaded to latest version - PR 729

  • Task DockerCreateContainer gained option groups - Pull Request 731

v4.3.0 (January 12, 2019)

  • Breaking Change! The task DockerLoadImage should use Provider type for image file

  • Breaking Change! Use the default value $buildDir/docker for DockerBuildImage.inputDir to align with the default directory of the Dockerfile task

  • Breaking Change! Align task names in DockerJavaApplicationPlugin with the ones from the DockerSpringBootApplicationPlugin

  • Examples in user guide that demonstrate the creation of a custom Docker task and the modification of existing Dockerfile instructions

v4.2.0 (December 16, 2018)

  • Applying the Docker Spring Boot application plugin with the plugins DSL should not fail - Issue 702

  • Breaking Change! Remove all deprecations - Issue 675

    • Removed DockerCreateContainer.env, replaced by DockerCreateContainer.envVars

    • Removed DockerBuildImage.tag, replaced by DockerBuildImage.tags

    • Removed DockerExecContainer.cmd, replaced by DockerExecContainer.commands

    • Removed DockerExecContainer.execId, replaced by DockerExecContainer.execIds

  • DockerBuildImage.tags.add/addAll only work after using tags.set - Issue 712

  • User guide sample on Docker links should not use doFirst - Issue 715

  • DockerCommitImage task should not fail when accessing container ID property value - Issue 718

v4.1.0 (November 29, 2018)

v4.0.5 (November 22, 2018)

  • Avoid the use of application plugin extension to ensure compatibility - Issue 706

v4.0.4 (November 4, 2018)

  • Implementation to make DockerBuildImage task incremental and cacheable is not sufficient - Issue 697

v4.0.3 (October 30, 2018)

  • Correctly handle the case where inputDir is not where dockerFile is located - Pull Request 693

v4.0.2 (October 27, 2018)

  • Output file name containing the image ID created by DockerBuildImage should work on Windows - Pull Request 690

v4.0.1 (October 20, 2018)

  • Returned image ID for a DockerBuildImage task should never be null - Pull Request 687

v4.0.0 (October 12, 2018)

  • Breaking Change! Use Provider concept throughout to support lazy evaluation via public API - Pull Request 659

  • Breaking Change! Consumers of this plugin will have to use Java 8 or higher - Pull Request 676

  • Breaking Change! Removal of AbstractReactiveStreamsTask from inherited custom task hierarchy

  • NEW Add tested, multi-lingual user guide - Pull Request 677

  • NEW Make DockerBuildImage task incremental and cacheable - Pull Request 672

  • Introduce method for translating username/password into a PasswordCredentials - Pull Request 668

  • Add @CompileStatic to much of the code base that can support it - Pull Request 676

  • Use appropriate types for Groovy/Kotlin DSL interoperability for reactive streams functionality - Pull Request 678

v3.6.2 (October 2, 2018)

  • DockerCreateContainer gained pid option - Pull Request 652

  • Dockerfile validation takes into account comments - Issue 657

  • Bump docker-java-shaded to rc-5 - Issue 660

  • DockerBuildImage gained network option - Issue 608

  • DockerCreateContainer gained autoRemove option - Issue 639

v3.6.1 (August 21, 2018)

  • Task DockerClient, and the passed dockerClient object, is now cached by configuration - Pull Request 644

  • Task DockerBuildImage gained option cacheFrom - Pull Request 646

v3.6.0 (August 7, 2018)

v3.5.0 (July 24, 2018)

v3.4.4 (July 15, 2018)

  • Task DockerLivenessContainer had its polling logic reworked to be more failure proof.

v3.4.3 (July 8, 2018)

  • Task DockerCreateContainer has its method withEnvVars changed to accept a def, which in turn can be anything (String, Integer, Closure, etc) but will eventually have all its keys/values resolved to java strings. - Pull Request 617

  • Task DockerLivenessContainer had minor verbiage changes to its output. - Pull Request 617

  • Use -all wrapper to better integrate with IDE’s. - Pull Request 617

v3.4.2 (July 7, 2018)

v3.4.1 (July 3, 2018)

  • BUGFIX for task DockerCreateContainer where envs were not being properly honored. - Pull Request 614

v3.4.0 (July 1, 2018)

  • Task Dockerfile now supports multi-stage builds - Pull Request 607

  • When plugin is applied to sub-projects we will additionally search rootProject for repos to use - Pull Request 610

  • Task DockerCreateContainer has deprecated env in favor of envVars which can ONLY be added to with a helper method withEnvVar that can be called N times for setting environment variables. - Pull Request 609

  • Task DockerLivenessProbeContainer has been renamed to DockerLivenessContainer. It’s probe method has been renamed to livnessProbe. Task DockerExecStopContainer had its probe method renamed to execStopProbe. - Pull Request 611

v3.3.6 (June 23, 2018)

  • Task DockerCopyFileToContainer can now copy N number of files via methods withFile and withTarFile. - Pull request 605

v3.3.5 (June 17, 2018)

  • Fix bug within DockerExecContainer when exitCode can be null (default to 0 if so). - Pull request 602

v3.3.4 (June 16, 2018)

  • Task DockerExecContainer gained ability to specify multiple execution commands to be run. - Pull request 600

  • Various tasks had their progress logger output cleaned up. - Pull request 601

v3.3.3 (June 8, 2018)

  • Explicitly call toString() on values in maps passed to Docker API. - Pull request 595

  • Task DockerLivenessProbeContainer gained method lastInspection() which will return the last "docker inspect container" response AFTER execution has completed. - Pull request 596

v3.3.2 (June 5, 2018)

  • Task DockerLivenessProbeContainer now has the probe option set to optional and if NOT defined will fallback to checking if container is in a running state. - Pull request 594

v3.3.1 (June 2, 2018)

  • Various minor refactorings surrounding new task DockerExecStopContainer. - Pull request 592

v3.3.0 (June 1, 2018)

  • Added task DockerClient to pass the raw docker-java client to the onNext closure if defined. - Pull request 589

  • Task DockerCreateContainer will now log the containerName if set, which is the standard within this plugin, otherwise fallback to the just created containerId.

  • Task DockerExecContainer gained option successOnExitCodes to allow user to define a list of successful exit codes the exec is allowed to return and will fail if not in list. Default behavior is to do no check. - Pull request 590

  • Added task DockerLivenessProbeContainer which will poll, for some defined amount of time, a running containers logs looking for a given message and fail if not found. - Pull request 587

  • Added task DockerExecStopContainer to allow the user to execute an arbitrary cmd against a container, polling for it to enter a non-running state, and if that does not succeed in time issue stop request. - Pull request 591

v3.2.9 (May 22, 2018)

  • Fixed a bug in task DockerCreateContainer where option cpuset is now renamed differently in docker-java. - Pull request 585

v3.2.8 (April 30, 2018)

  • Task DockerExecContainer gained option user to specify a user/group. - Pull request 574

  • Task DockerCreateContainer gained option ipV4Address to specify a specific ipv4 address to use. - Pull request 449

  • Bump gradle to 4.7. - Pull request 578

v3.2.7 (April 19, 2018)

  • Task DockerSaveImage gained option useCompression to optionally gzip the created tar. - Pull request 565

  • Add javax.activation dependency for users who are working with jdk9+. - Pull request 572

v3.2.6 (March 31, 2018)

  • Cache docker-java client instead of recreating for every request/task invocation. This is a somewhat big internal change but has a lot of consequences and so it was deserving of its own point release. - Pull request 558

v3.2.5 (March 2, 2018)

  • Added macAddress option to task DockerCreateContainer - Pull request 538

  • Initial work for codenarc analysis - Pull request 537

  • Use of docker-java-shaded library in favor of docker-java proper to get around class-loading/clobbering issues - Pull request 550

  • Honor DOCKER_CERT_PATH env var if present - Pull request 549

  • Task DockerSaveImage will now create file for you should it not exist - Pull request 552

  • Task DockerPushImage will now include tag info in logging if applicable - Pull request 554

  • !!!!! BREAKING: Property inputStream of task DockerLoadImage has been changed from type InputStream to Closure<InputStream>. This was done to allow scripts/code/pipelines to delay getting the image and side-step this property getting configured during gradles config-phase. - Pull request 552

v3.2.4 (February 5, 2018)

v3.2.3 (January 26, 2018)

  • If DockerWaitHealthyContainer is run on an image which was not built with HEALTHCHECK than fallback to using generic status - Pull request 520

v3.2.2 (January 17, 2018)

v3.2.1 (November 22, 2017)

v3.2.0 (September 29, 2017)

  • Update createBind to use docker-java parse method - Pull request 452

  • Allow Docker to cache app libraries dir when DockerJavaApplication plugin is used - Pull request 459

v3.1.0 (August 21, 2017)

  • DockerListImages gained better support for filters - Pull request 414

  • Use alpine:3.4 image in functional tests - Pull request 416

  • DockerBuildImage and DockerCreateContainer gained optional argument shmSize - Pull request 413

  • Added tasks DockerInspectNetwork, DockerCreateNetwork, and DockerRemoveNetwork - Pull request 422

  • Add statically typed methods for configuring plugin with Kotlin - Pull request 426

  • Fix Dockerfile task up-to-date logic - Pull request 433

  • Multiple ENVs are not set the same way as single ENV instructions - Pull request 415

  • DockerCreateContainer changed optional input networkMode to network to better align with docker standatds - Pull request 440

  • The first instruction of a Dockerfile has to be FROM except for Docker versions later than 17.05 - Pull request 435

  • Bump verison of docker-java to 3.0.13 - Commit b2d936

v3.0.10 (July 7, 2017)

v3.0.9 (July 4, 2017)

v3.0.8 (June 16, 2017)

  • Task DockerPullImage gained method getImageId() which returns the fully qualified imageId of the image that was just pulled - Pull request 379

  • Task DockerBuildImage gained property tags which allows for multiple tags to be specified when building an image - Pull request 380

  • Task DockerCreateContainer gained property networkAliases - Pull request 384

v3.0.7 (May 17, 2017)

  • Invoke onNext closures call() method explicitly - Pull request 368

  • Adds new task DockerInspectExecContainer which allows to inspect exec instance - Pull request 362

  • `functionalTest’s can now run against a native docker instance - Pull request 369

  • DockerLogsContainer now preserves leading space - Pull request 370

  • Allow customization of app plugin entrypoint/cmd instructions - Pull request 359

  • Task Dockerfile will no longer be forced as UP-TO-DATE, instead the onus will be put on developers to code this should they want this functionality. - Issue 357

  • Now that functionalTest’s work natively, and in CI, add the test `started, passed and failed logging messages so as to make it absolutely clear to users what is being run vs having no output at all. - Pull request 373

  • Bump docker-java to v`3.0.10` - Pull request 378

v3.0.6 (March 2, 2017)

v3.0.5 (December 27, 2016)

v3.0.4 (December 1, 2016)

v3.0.3 (September 6, 2016)

v3.0.2 (August 14, 2016)

v3.0.1 (July 6, 2016)

  • Simplify Gradle TestKit usage - Pull request 225

  • Ensure tlsVerify is set in addition to certPath for DockerClientConfig setup - Pull request 230

  • Upgrade to Gradle 2.14.

v3.0.0 (June 5, 2016)

  • Task DockerLogsContainer gained attribute sink - Pull request 203

  • Task DockerBuildImage will no longer insert extra newline as part of build output - Pull request 206

  • Upgrade to docker-java 3.0.0 - Pull request 217

  • Fallback to buildscript.repositories for internal dependency resolution if no repositories were defined - Pull request 218

  • Added task DockerExecContainer - Pull request 221

  • Added task DockerCopyFileToContainer - Pull request 222

  • Task DockerCreateContainer gained attribute restartPolicy - Pull request 224

  • Remove use of Gradle internal methods.

  • Added ISSUES.md file.

  • Upgrade to Gradle 2.13.

v2.6.8 (April 10, 2016)

v2.6.7 (March 10, 2016)

  • Upgrade to Gradle 2.11.

  • Bug fix when copying single file from container and hostPath is set to directory for DockerCopyFileFromContainer - Pull request 163

  • Step reports are now printed to stdout by default for DockerBuildImage - Pull request 145

  • UP-TO-DATE functionality has been removed from DockerBuildImage as there were too many corner cases to account for - Pull request 172

v2.6.6 (February 27, 2016)

v2.6.5 (January 16, 2016)

v2.6.4 (December 24, 2015)

v2.6.3 (December 23, 2015)

  • Expose force and removeVolumes properties on DockerRemoveContainer - Pull request 129.

v2.6.2 (December 22, 2015)

  • Expose support for LogDriver on DockerCreateContainer - Pull request 118.

  • Upgrade to Docker Java 2.1.2.

v2.6.1 (September 21, 2015)

  • Correct the withVolumesFrom call on DockerCreateContainer task which needs to get a VolumesFrom[] array as the parameter - Pull request 102.

  • Upgrade to Docker Java 2.1.1 - Pull request 109.

v2.6 (August 30, 2015)

  • Upgrade to Docker Java 2.1.0 - Pull request 92. Note: The Docker Java API changed vastly with v2.0.0. The tasks DockerBuildImage, DockerPullImage and DockerPushImage do not provide a response handler anymore. This is a breaking change. Future versions of the plugin might open up the response handling again in some way.

  • DockerListImages with filter call a wrong function from ListImagesCmdImpl.java - Issue 105.

v2.5.2 (August 15, 2015)

  • Fix listImages task throwing GroovyCastException - Issue 96.

  • Add support for publishAll in DockerCreateContainer - Pull request 94.

  • Add optional dockerFile option to the DockerBuildImage task - Pull request 47.

v2.5.1 (July 29, 2015)

  • Adds Dockerfile support for the LABEL instruction - Pull request 86.

  • Usage of docker-java library v1.4.0. Underlying API does not provide setting port bindings for task DockerStartContainer anymore. Needs to be set on DockerCreateContainer.

v2.5 (July 18, 2015)

  • Expose response handler for DockerListImages task - v[Issue 75].

  • Pass in credentials when building an image - Issue 76.

v2.4.1 (July 4, 2015)

v2.4 (May 16, 2015)

  • Added missing support for properties portBindings and cpuset in CreateContainer - Pull request 66.

  • Expose response handlers so users can inject custom handling logic - Issue 65.

  • Upgrade to Gradle 2.4 including all compatible plugins and libraries.

v2.3.1 (April 25, 2015)

v2.3 (April 18, 2015)

v2.2 (April 12, 2015)

v2.1 (March 24, 2015)

  • Renamed property registry to registryCredentials for plugin extension and tasks implementing RegistryCredentialsAware to better indicate its purpose. Note: This is a breaking change.

v2.0.3 (March 20, 2015)

  • Allow for specifying port bindings for container start command. - Issue 30.

  • Throw an exception if an error response is encountered - Issue 37.

  • Upgrade to Gradle 2.3.

v2.0.2 (February 19, 2015)

  • Set source and target compatibility to Java 6 - Issue 32.

v2.0.1 (February 10, 2015)

  • Extension configuration method for DockerJavaApplicationPlugin needs to be registered via extension instance - Issue 28.

v2.0 (February 4, 2015)

  • Upgrade to Gradle 2.2.1 including all compatible plugins and libraries.

v0.8.3 (February 4, 2015)

  • Add project group to default tag built by Docker Java application plugin - Issue 25.

v0.8.2 (January 30, 2015)

  • Expose method for task Dockerfile for providing vanilla Docker instructions.

v0.8.1 (January 24, 2015)

v0.8 (January 7, 2014)

  • Allow for pushing to Docker Hub - Issue 18.

  • Better handling of API responses.

  • Note: Change to plugin extension. The property docker.serverUrl is now called docker.url. Instead of docker.credentials, you will need to use docker.registry.

v0.7.2 (December 23, 2014)

  • Dockerfile task is always marked UP-TO-DATE after first execution - Issue 13.

  • Improvements to Dockerfile task - Pull request 16.

  • Fixed wrong assignment of key field in environment variable instruction.

  • Allow for providing multiple ports to the expose instruction.

v0.7.1 (December 16, 2014)

  • Fixed entry point definition of Dockerfile set by Java application plugin.

v0.7 (December 14, 2014)

  • Allow for properly add user-based instructions to Dockfile task with predefined instructions without messing up the order. - Issue 12.

  • Renamed task dockerCopyDistTar to dockerCopyDistResources to better express intent.

v0.6.1 (December 11, 2014)

  • Allow for setting path to certificates for communicating with Docker over SSL - Issue 10.

v0.6 (December 7, 2014)

  • Usage of docker-java library v0.10.4.

  • Added Docker Java application plugin.

  • Better documentation.

v0.5 (December 6, 2014)

  • Fixed implementations of tasks DockerPushImage and DockerCommitImage - Issue 11.

v0.4 (November 27, 2014)

  • Added task for creating a Dockerfile.

v0.3 (November 23, 2014)

  • Usage of docker-java library v0.10.3.

  • Changed package name to com.bmuschko.gradle.docker.

  • Changed group ID to com.bmuschko.

  • Adapted plugin IDs to be compatible with Gradle’s plugin portal.

v0.2 (June 19, 2014)

  • Usage of docker-java library v0.8.2.

  • Provide custom task type for push operation.

  • Support for using remote URLs when building image - Issue 3.

v0.1 (May 11, 2014)

  • Initial release.