-
Notifications
You must be signed in to change notification settings - Fork 12
Home
The plugin relies on the application plugin, which offers the distTar task; the distTar task will create a tarball using name format applicationName-version.tar (e.g. application-1.0.1.tar). This tarball will unpack in a directory which contains the version number (e.g. application-1.0.1 in the above example) -- and as such when applying the gradle-docker-plugin the entry point to the docker image would be set in this case to /application-1.0.1/bin/application. Each incremental version will see a change in the tarball name and therefore in the docker image entry point. This has the implication of having to update other systems which need to start the docker image with the new version/path.
(Please note that relies in the above paragraph refers to the fact that you have to apply the application plugin to your gradle build before applying this plugin.)
To eliminate this issue, the plugin adds a symlink in the docker image : appicationName-latest -> applicationName-version directory and then uses the symlink to define the docker image entry point to be application-latest/bin/application. The distTar plugin will still generate a versioned tar and directory as per before, but simply adding the symlink in the docker image means that the docker image entry point is consistent across different versions of the docker image.
Also, using the gradle-docker-plugin requires a lot of boilerplate code to customize the docker image (add files, symlinks, execute commands etc) -- this plugin handles all of that and allows for a simple closure to be defined to handle constructing the docker image.
Tagging a docker image again requires boilerplate -- the nebula.docker plugin by default tags the docker image with the application version number as well as latest. It also allows for a closure to be defined to set the tag/version of the docker image.
There are a few other customizations the plugin offers -- see the section below for more details on this.
Reference the plugin in your buildscript section:
buildscript {
repositories { jcenter() }
dependencies {
classpath "com.netflix.nebula:nebula-docker-plugin:latest.release"
}
}
Note that you can use a specific version if you want rather than latest.release. Then simply apply the plugin in your build.gradle (remember you have to also apply the application plugin before this plugin):
apply plugin: 'application'
apply plugin: 'nebula.docker'
That's it! The plugin will build the docker image and publish it for you.
See the section below for customizing the plugin.
The plugin exports an instance of NebulaDockerExtension via project.nebulaDocker -- which allows you to customize various aspects of the plugin execution as follows:
nebulaDocker {
maintainerEmail = '[email protected]'
dockerUrl = 'http://docker.host.com'
dockerBase = 'java:openjdk-8-jre'
dockerFile = '/some/build/dir/Dockerfile'
appDir = '/myapp-name'
appDirLatest = '/myapp-latest
dockerRepo = [test:'http://repo.for.test.com', prod: 'https://prod.repo.url/path', dev: 'http://localhost:port/some/path']
dockerImage = {
addFile 'my_properties.properties', '/path/etc'
...
}
tagVersion = {
def x = computeX()
def y = computeY()
"some-version-i-want-set.${x}.${y}"
}
}
where:
| Field | Type | Default Value (if not set) | Description |
|---|---|---|---|
maintainerEmail |
String |
null (not set) |
Email address of the maintainer of this docker image |
dockerUrl |
String | "http://localhost:4243" | URL used to communicate with the docker process to build the image etc |
dockerBase |
String | "java:openjdk-8-jre" | Base docker image to extend / build your docker image from |
dockerFile |
String | "./build/docker/Dockerfile" | Location of the Dockerfile in your build. If you have a handcrafted Dockerfile specify it here. |
appDir |
String | "/${project.applicationName}-${project.version}" | Directory in the docker image where your app will be unpacked. |
appDirLatest |
String | "/${project.applicationName}-latest" | Symlink directory which will be symlink to the appDir folder and be set to the entry point in the docker image. |
dockerRepo |
Map<String,String | Closure> | [test: "titan-registry.main.us-east-1.dyntest.netflix.net:7001/${project.group}/${project.applicationName}", prod: "titan-registry.main.us-east-1.dynprod.netflix.net:7001/${project.group}/${project.applicationName}"] |
dockerImage |
Closure |
null (not set) |
Closure to execute when building the docker image. By default the code just creates the appDir directory and symlinks appDirLatest to it and sets the entry point to the shell script in appDirLatest/bin. If you need any other files or symlinks or commands to be executed, specify them here. |
tagVersion |
Closure | { "${project.version}" } |
Closure used to set the tag on the docker image. Typically the code will set 2 tags: one with the application version and one with latest. This closure allows you to define the tagging for the application version. |
dockerRepoAuth |
boolean | false |
This is a simple flag to indicate whether or not to add registryCredentials to the underlying docker extension for specifying user credentials. See also dockerRepoUsername and dockerRepoPassword. |
dockerRepoUsername |
String |
null (not set) |
The username to use when registry auth is enabled via dockerRepoAuth. See also dockerRepoPassword. |
dockerRepoPassword |
String |
null (not set) |
The password to use when registry auth is enabled via dockerRepoAuth. See also dockerRepoUsername. |
dockerRepoEmail |
String |
null (not set) |
The email address to use for docker repo authentication (see dockerRepoAuth). |
tagWithoutPush |
boolean | false | Do we only tag images (locally) or also push the tags to origin. |
This is provided for reference, but this is the equivalent boilerplate code the plugin replaces:
...
apply plugin: 'com.bmuschko.docker-java-application'
...
def dockerRepositoryProd = "repository.docker.test.net/${project.group}/${project.applicationName}"
def dockerRepositoryTest = "repository.docker.production.com/${project.group}/${project.applicationName}"
def dockerBase = 'java:openjdk-8-jre'
...
buildscript { dependencies { classpath "com.bmuschko:gradle-docker-plugin:$dockerVersion" } }
docker {
url = 'http://docker.url.com:port'
javaApplication {
baseImage = dockerBase
maintainer = '[email protected]'
}
}
import com.bmuschko.gradle.docker.tasks.image.DockerBuildImage
import com.bmuschko.gradle.docker.tasks.image.DockerTagImage
import com.bmuschko.gradle.docker.tasks.image.DockerPushImage
import com.bmuschko.gradle.docker.tasks.image.Dockerfile
afterEvaluate {
def appDir = "/${project.applicationName}-${project.version}"
def appDirLatest = "/${project.applicationName}-latest"
task createDockerfile(type: Dockerfile) {
destFile = project.file('./build/docker/Dockerfile')
dependsOn distTar
dependsOn dockerCopyDistResources
from "$dockerBase"
maintainer '[email protected]'
println "Using tar: ${distTar.archiveName}"
addFile "${distTar.archiveName}", '/'
runCommand "ln -s ${appDir} ${appDirLatest}"
entryPoint "${appDir}/bin/${project.applicationName}"
}
task buildImage(type: DockerBuildImage) {
dependsOn createDockerfile
inputDir = createDockerfile.destFile.parentFile
}
// TEST
task dockerTagImageTest(type: DockerTagImage) {
dependsOn buildImage
targetImageId { buildImage.imageId }
repository = dockerRepositoryTest
conventionMapping.tag = { project.version }
force = true
}
task pushImageTest(type: DockerPushImage) {
dependsOn dockerTagImageTest
conventionMapping.imageName = { dockerTagImageTest.getRepository() }
conventionMapping.tag = { dockerTagImageTest.getTag() }
}
task dockerTagImageTestLatest(type: DockerTagImage) {
dependsOn pushImageTest
targetImageId { buildImage.imageId }
repository = dockerRepositoryTest
conventionMapping.tag = { 'latest' }
force = true
}
task pushImageTestLatest(type: DockerPushImage) {
dependsOn dockerTagImageTestLatest
conventionMapping.imageName = { dockerTagImageTest.getRepository() }
conventionMapping.tag = { dockerTagImageTestLatest.getTag() }
}
// PROD
task dockerTagImageProd(type: DockerTagImage) {
dependsOn buildImage
targetImageId { buildImage.imageId }
repository = dockerRepositoryProd
conventionMapping.tag = { project.version }
force = true
}
task pushImageProd(type: DockerPushImage) {
dependsOn dockerTagImageProd
conventionMapping.imageName = { dockerTagImageProd.getRepository() }
conventionMapping.tag = { dockerTagImageProd.getTag() }
}
task dockerTagImageProdLatest(type: DockerTagImage) {
dependsOn pushImageProd
targetImageId { buildImage.imageId }
repository = dockerRepositoryProd
conventionMapping.tag = { 'latest' }
force = true
}
task pushImageProdLatest(type: DockerPushImage) {
dependsOn dockerTagImageProdLatest
conventionMapping.imageName = { dockerTagImageProd.getRepository() }
conventionMapping.tag = { dockerTagImageProdLatest.getTag() }
}
task pushAllImages {
dependsOn pushImageTestLatest, pushImageProdLatest
}
}
NOTE The code above only defines test and prod environments, if one needs to add an extra environment, need to copy dockerTagImagexxx, pushImagexxx, dockerTagImagexxxLatest and pushImagexxxLatest and adjust as well as alter pushAllImages to include those tasks in dependencies.
With this plugin, simply add another entry in the dockerRepo property.