Cloud Native Blog - Container Solutions

How to build Docker images with Gradle

Written by Frank Scholten | Jun 5, 2015 1:03:42 PM

In this blog I will show you how to build Docker images from a Gradle task. A number of Docker plugins have been created for Gradle. I discuss the one from Benjamin Muschko which we use to build the scheduler image for Mesos Elasticsearch. This plugin is quite versatile because it provides Gradle tasks for almost every Docker CLI command.

Docker images used by Mesos Elasticsearch

In Mesos Elasticsearch we build two Docker images. The first image, mesos/elasticsearch-scheduler is an image which contains the executable jar of the Elasticsearch scheduler. By creating an image for it we can deploy it via Marathon. The second image, mesos/elasticsearch-cloud-mesos contains elasticsearch and the cloud-mesos plugin and it is used by containers launched by the scheduler. In this blog I will show how to build these containers with Gradle. If you want to know more about Mesos Elasticsearch itself, checkout the Mesos Elasticsearch Github page. The project is sponsored by Cisco Cloud Services.

Enabling the Docker plugin in Gradle

Now let's talk about Gradle. To enable @bmuschko's Docker plugin add the following line to the top of build.gradle.


apply plugin: 'com.bmuschko.docker-remote-api'

Then you also have to add the repository where Gradle can download the plugin from.


buildscript {
  repositories {
   jcenter()
  }
  dependencies {
    classpath 'com.bmuschko:gradle-docker-plugin:2.2'
  }
}
	
	

 

Docker Gradle tasks

Below I will explain how to build the mesos/elasticsearch-scheduler image. Have a look at the snippet from scheduler/build.gradle. I removed the dependencies and buildscript definitions as they are not relevant here.


jar {
    baseName = "elasticsearch-mesos-scheduler"
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    manifest { attributes 'Main-Class': 'org.apache.mesos.elasticsearch.scheduler.ElasticsearchScheduler' }
}
 
task copyJar(type: Copy) {
    dependsOn   'jar'
    from        "build/libs/elasticsearch-mesos-scheduler-${project.version}.jar"
    into        'build/docker'
    rename { String fileName ->
        fileName.replace("-${project.version}", "")
    }
}
 
task buildDockerImage(type: DockerBuildImage) {
    dependsOn   copyJar
    if (System.env.DOCKER_HOST) {
        url = "$System.env.DOCKER_HOST".replace("tcp","https")
        if (System.env.DOCKER_CERT_PATH) {
            certPath = new File(System.env.DOCKER_CERT_PATH)
 
        }
    }
    else {
        url = 'unix:///var/run/docker.sock'
    }
    inputDir = file('.')
    tag = 'mesos/elasticsearch-scheduler'
}
 
build.dependsOn buildDockerImage
build.dependsOn copyJar
	
	

There are 3 tasks. The first task, jar, builds the executable scheduler jar including it's dependencies. Before we can build the Docker image we have to copy this jar to the build/docker folder. This is done by the second task: copy. The version is stripped so that the Dockerfile CMD is always java -jar elasticsearch-mesos-scheduler.jar . Finally in the third task we run the docker task. It has the type DockerBuildImage and it has a dependency on the copy task, sets the inputDir and connect either to DOCKER_HOST or uses the socket.

Update 01-07-2016 - Make sure you use the correct Docker context when you have multiple Docker Machines. Run 'eval "$(docker-machine env)'. Kudos to Abhijit Sarkar for pointing this out in the comment below.

As you can see building Docker images with Gradle is relatively straightforward. For more information on other Docker tasks, checkout the other Docker Gradle task types