Coder Social home page Coder Social logo

gradle-docker's Introduction

Autorelease

Docker Gradle Plugin

Build Status Gradle Plugins Release

Disclaimer: This Repo is now Defunct

  • This repo is on life support only - although we will keep it working, no new features are accepted;
  • It is no longer used internally at Palantir.

Docker Plugin

This repository provides three Gradle plugins for working with Docker containers:

  • com.palantir.docker: add basic tasks for building and pushing docker images based on a simple configuration block that specifies the container name, the Dockerfile, task dependencies, and any additional file resources required for the Docker build.
  • com.palantir.docker-compose: adds a task for populating placeholders in a docker-compose template file with image versions resolved from dependencies.
  • com.palantir.docker-run: adds tasks for starting, stopping, statusing and cleaning up a named container based on a specified image

Apply the plugin using standard gradle convention:

plugins {
    id 'com.palantir.docker' version '<version>'
}

Set the container name, and then optionally specify a Dockerfile, any task dependencies and file resources required for the Docker build. This plugin will automatically include outputs of task dependencies in the Docker build context.

Docker Configuration Parameters

  • name the name to use for this container, may include a tag
  • tags (deprecated) (optional) an argument list of tags to create; any tag in name will be stripped before applying a specific tag; defaults to the empty set
  • tag (optional) a tag to create with a specified task name
  • dockerfile (optional) the dockerfile to use for building the image; defaults to project.file('Dockerfile') and must be a file object
  • files (optional) an argument list of files to be included in the Docker build context, evaluated per Project#files. For example, files tasks.distTar.outputs adds the TAR/TGZ file produced by the distTar tasks, and files tasks.distTar.outputs, 'my-file.txt' adds the archive in addition to file my-file.txt from the project root directory. The specified files are collected in a Gradle CopySpec which may be copied into the Docker build context directory. The underlying CopySpec may also be used to copy entire directories into the build context. The following example adds the aforementioned archive and text file to the CopySpec, uses the CopySpec to add all files from src/myDir into the CopySpec, then finally executes the copy into the directory myDir in docker build context.
docker {
    files tasks.distTar.outputs, 'my-file.txt'
    copySpec.from("src/myDir").into("myDir")
}

The final structure will be:

build/
  docker/
    myDir/
      my-file.txt
      // contents of task.distTar.outputs
      // files from src/myDir
  • buildArgs (optional) an argument map of string to string which will set --build-arg arguments to the docker build command; defaults to empty, which results in no --build-arg parameters
  • labels (optional) a map of string to string which will set --label arguments to the docker build command; defaults to empty, which results in no labels applied.
  • pull (optional) a boolean argument which defines whether Docker should attempt to pull a newer version of the base image before building; defaults to false
  • noCache (optional) a boolean argument which defines whether Docker build should add the option --no-cache, so that it rebuilds the whole image from scratch; defaults to false
  • buildx (optional) a boolean argument which defines whether Docker build should use buildx for cross platform builds; defaults to false
  • platform (optional) a list of strings argument which defines which platforms buildx should target; defaults to empty
  • builder (optional) a string argument which defines which builder buildx should use; defaults to null
  • load (optional) a boolean argument which defines whether Docker buildx builder should add --load flag, loading the image into the local repository; defaults to false
  • push (optional) a boolean argument which defines whether Docker buildx builder should add --push flag, pushing the image into the remote registry; defaults to false

To build a docker container, run the docker task. To push that container to a docker repository, run the dockerPush task.

Tag and Push tasks for each tag will be generated for each provided tag and tags entry.

Examples

Simplest configuration:

docker {
    name 'hub.docker.com/username/my-app:version'
}

Canonical configuration for building a Docker image from a distribution archive:

// Assumes that Gradle "distribution" plugin is applied
docker {
    name 'hub.docker.com/username/my-app:version'
    files tasks.distTar.outputs   // adds resulting *.tgz to the build context
}

Configuration specifying all parameters:

docker {
    name 'hub.docker.com/username/my-app:version'
    tags 'latest' // deprecated, use 'tag'
    tag 'myRegistry', 'my.registry.com/username/my-app:version'
    dockerfile file('Dockerfile')
    files tasks.distTar.outputs, 'file1.txt', 'file2.txt'
    buildArgs([BUILD_VERSION: 'version'])
    labels(['key': 'value'])
    pull true
    noCache true
}

Managing Docker image dependencies

The com.palantir.docker and com.palantir.docker-compose plugins provide functionality to declare and resolve version-aware dependencies between docker images. The primary use-case is to generate docker-compose.yml files whose image versions are mutually compatible and up-to-date in cases where multiple images depend on the existence of the same Dockerized service.

Specifying and publishing dependencies on Docker images

The docker plugin adds a docker Gradle component and a docker Gradle configuration that can be used to specify and publish dependencies on other Docker containers.

Example

plugins {
    id 'maven-publish'
    id 'com.palantir.docker'
}

...

dependencies {
    docker 'foogroup:barmodule:0.1.2'
    docker project(":someSubProject")
}

publishing {
    publications {
        dockerPublication(MavenPublication) {
            from components.docker
            artifactId project.name + "-docker"
        }
    }
}

The above configuration adds a Maven publication that specifies dependencies on barmodule and the someSubProject Gradle sub project. The resulting POM file has two dependency entries, one for each dependency. Each project can declare its dependencies on other docker images and publish an artifact advertising those dependencies.

Generating docker-compose.yml files from dependencies

The com.palantir.docker-compose plugin uses the transitive dependencies of the docker configuration to populate a docker-compose.yml.template file with the image versions specified by this project and all its transitive dependencies. The plugin uses standard Maven/Ivy machanism for declaring and resolving dependencies.

The generateDockerCompose task generates a docker-compose.yml file from a user-defined template by replacing each version variable by the concrete version declared by the transitive dependencies of the docker configuration. The task performs two operations: First, it generates a mapping group:name --> version from the dependencies of the docker configuration (see above). Second, it replaces all occurrences of version variables of the form {{group:name}} in the docker-compose.yml.template file by the resolved versions and writes the resulting file as docker-compose.yml.

The docker-compose plugin also provides a dockerComposeUp task that starts the docker images specified in the dockerComposeFile in detached mode. You can also use the dockerComposeDown task to stop the containers.

Example

Assume a docker-compose.yml.template as follows:

myservice:
  image: 'repository/myservice:latest'
otherservice:
  image: 'repository/otherservice:{{othergroup:otherservice}}'

build.gradle declares a dependency on a docker image published as 'othergroup:otherservice' in version 0.1.2:

plugins {
    id 'com.palantir.docker-compose'
}

dependencies {
    docker 'othergroup:otherservice:0.1.2'
}

The generateDockerCompose task creates a docker-compose.yml as follows:

myservice:
  image: 'repository/myservice:latest'
otherservice:
  image: 'repository/otherservice:0.1.2'

The generateDockerCompose task fails if the template file contains variables that cannot get resolved using the provided docker dependencies. Version conflicts between transitive dependencies of the same artifact are handled with the standard Gradle semantics: each artifact is resolved to the highest declared version.

Configuring file locations

The template and generated file locations are customizable through the dockerCompose extension:

dockerCompose {
    template 'my-template.yml'
    dockerComposeFile 'my-docker-compose.yml'
}

Docker Run Plugin

Apply the plugin using standard gradle convention:

plugins {
    id 'com.palantir.docker-run' version '<version>'
}

Use the dockerRun configuration block to configure the name, image and optional command to execute for the dockerRun tasks:

dockerRun {
    name 'my-container'
    image 'busybox'
    volumes 'hostvolume': '/containervolume'
    ports '7080:5000'
    daemonize true
    env 'MYVAR1': 'MYVALUE1', 'MYVAR2': 'MYVALUE2'
    command 'sleep', '100'
    arguments '--hostname=custom', '-P'
}

Docker Run Configuration Parameters

  • name the name to use for this container, may include a tag.
  • image the name of the image to use.
  • volumes optional map of volumes to mount in the container. The key is the path to the host volume, resolved using project.file(). The value is the exposed container volume path.
  • ports optional mapping local:container of local port to container port.
  • env optional map of environment variables to supply to the running container. These must be exposed in the Dockerfile with ENV instructions.
  • daemonize defaults to true to daemonize the container after starting. However if your container runs a command and exits, you can set this to false.
  • ignoreExitValue (optional) to ignore the exit code returned from the execution of the docker command; defaults to false
  • clean (optional) a boolean argument which adds --rm to the docker run command to ensure that containers are cleaned up after running; defaults to false
  • command the command to run.
  • arguments additional arguments to be passed into the docker run command. Please see https://docs.docker.com/engine/reference/run/ for possible values.

Tasks

  • Docker
    • docker: build a docker image with the specified name and Dockerfile
    • dockerTag: tag the docker image with all specified tags
    • dockerTag<tag>: tag the docker image with <tag>
    • dockerPush: push the specified image to a docker repository
    • dockerPush<tag>: push the <tag> docker image to a docker repository
    • dockerTagsPush: push all tagged docker images to a docker repository
    • dockerPrepare: prepare to build a docker image by copying dependent task outputs, referenced files, and dockerfile into a temporary directory
    • dockerClean: remove temporary directory associated with the docker build
    • dockerfileZip: builds a ZIP file containing the configured Dockerfile
  • Docker Compose
    • generateDockerCompose: Populates a docker-compose file template with image versions declared by dependencies
    • dockerComposeUp: Brings up services defined in dockerComposeFile in detacted state
    • dockerComposeDown: Stops services defined in dockerComposeFile
  • Docker Run
    • dockerRun: run the specified image with the specified name
    • dockerStop: stop the running container
    • dockerRunStatus: indicate the run status of the container
    • dockerRemoveContainer: remove the container

License

This plugin is made available under the Apache 2.0 License.

Contributing

Contributions to this project must follow the contribution guide.

gradle-docker's People

Contributors

a10y avatar andybradshaw avatar bitterpeanut avatar bulldozer-bot[bot] avatar crogers avatar dansanduleac avatar darora avatar dbalakirev avatar fawind avatar ferozco avatar giancarlobastos avatar guenhter avatar henryptung avatar iamdanfox avatar kyegupov avatar markelliot avatar michael-yx-wu avatar rmelick avatar ryanhartkopf avatar samrogerson avatar sanggggg avatar saw303 avatar shacker27 avatar sshankar avatar stefan-huettemann avatar svc-autorelease avatar svc-excavator-bot avatar tmccarthy avatar uschi2000 avatar yiweny avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gradle-docker's Issues

How do I push a dynamic tag

I can push latest tag, but I want to be able to push a dynamically generated tag to a private repo

docker {
    name 'my.private.registry/' + project.artifactName
    tags 'latest', "$project.version"
    dependsOn tasks.build
}

task pushDockerTags() {
    tasks["dockerPush$project.version"]
    dependsOn docker
}

afterReleaseBuild.dependsOn pushDockerTags

I get the following error:
A problem occurred evaluating root project 'my-artifactName'.

Task with name 'dockerPush0.0.1-SNAPSHOT' not found in root project 'my-project-name'.

Is this possible ?
thanks for help.

Docker build context (build/docker dir)

I may be miss-using the plugin, please let me know if that is the case.

I configured a new project according to examples, what I observe is that entire project (minus build/) is copied to build/docker. I causes an unnecessary large docker build context.

Is there a way to prevent that?
Inspecting source I see it was not supposed to to copy everything when ext.resolvedFiles has value.

Thanks

How can I use dockerPush<tag> with dependsOn?

I want to execute dockerPushlatest with dependsOn taks, my config is:

task testingDockerPushLatest(){
    dependsOn tasks.dockerPushlatest
}

But I'm getting this error:

Could not get unknown property 'dockerPushlatest' for task set.

using parameter 'files' does not lead to expected results with directories

Hi & thank you for this nice plugin.

We have an issue (questions) with configuring docker using the files parameter:

docker {
    name 'myContainer'
    files 'x'
}

where x is a directory.

We would expect that the directory x (including all its contents) will get copied to the build/docker area.

Instead only the content of directory x gets copied (not the directory x itself).

Using the configuration below leads to the result we would expect from the files parameter:

dockerPrepare {
    from('.') {
        include 'x'
    }
}

Questions:

  1. Is this a 'feature' of the files parameter?
  2. Is the configuration as stated above intended to be used a such by the design of the plugin?

Thank & Regards
-Stefan

Feature Request: Support for general arguments in docker-run

I need to set the --net option on my container started with the docker-run plugin, but cannot since it is not one of the supported options. In general, there are a lot of options that can be set in the docker run command (https://docs.docker.com/engine/reference/run/). Would it make sense to build a new general option for the docker-run plugin (perhaps based on a String->String map) that allowed the user to specify arbitrary parameters to the docker run command?

Error after updating gradle to 3.4-rc-1

I'm trying to upgrade gradle from 3.3.0 to latest and whenever I run ./gradlew wrapper, I get the following error:

org.gradle.api.GradleScriptException: A problem occurred evaluating project '<subproject>'.
        at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:92)
        at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl$2.run(DefaultScriptPluginFactory.java:176)
        at org.gradle.configuration.ProjectScriptTarget.addConfiguration(ProjectScriptTarget.java:77)
        at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl.apply(DefaultScriptPluginFactory.java:181)
        at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:39)
        at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:26)
        at org.gradle.configuration.project.ConfigureActionsProjectEvaluator.evaluate(ConfigureActionsProjectEvaluator.java:34)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.doConfigure(LifecycleProjectEvaluator.java:70)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.access$000(LifecycleProjectEvaluator.java:33)
        at org.gradle.configuration.project.LifecycleProjectEvaluator$1.execute(LifecycleProjectEvaluator.java:53)
        at org.gradle.configuration.project.LifecycleProjectEvaluator$1.execute(LifecycleProjectEvaluator.java:50)
        at org.gradle.internal.Transformers$4.transform(Transformers.java:169)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:61)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:50)
        at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:599)
        at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:125)
        at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:35)
        at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:62)
        at org.gradle.configuration.DefaultBuildConfigurer.configure(DefaultBuildConfigurer.java:38)
        at org.gradle.initialization.DefaultGradleLauncher$ConfigureBuildAction.execute(DefaultGradleLauncher.java:233)
        at org.gradle.initialization.DefaultGradleLauncher$ConfigureBuildAction.execute(DefaultGradleLauncher.java:230)
        at org.gradle.internal.Transformers$4.transform(Transformers.java:169)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:56)
        at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:160)
        at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:119)
        at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:102)
        at org.gradle.launcher.exec.GradleBuildController.run(GradleBuildController.java:71)
        at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28)
        at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:41)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:26)
        at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:75)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
        at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:46)
Caused by: java.lang.NoClassDefFoundError: org/gradle/api/internal/component/Usage
        at com.palantir.gradle.docker.PalantirDockerPlugin.apply(PalantirDockerPlugin.groovy:74)
        at com.palantir.gradle.docker.PalantirDockerPlugin.apply(PalantirDockerPlugin.groovy)
        at org.gradle.api.internal.plugins.ImperativeOnlyPluginApplicator.applyImperative(ImperativeOnlyPluginApplicator.java:35)
        at org.gradle.api.internal.plugins.RuleBasedPluginApplicator.applyImperative(RuleBasedPluginApplicator.java:43)
        at org.gradle.api.internal.plugins.DefaultPluginManager.doApply(DefaultPluginManager.java:139)
        at org.gradle.api.internal.plugins.DefaultPluginManager.apply(DefaultPluginManager.java:112)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.applyType(DefaultObjectConfigurationAction.java:113)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.access$200(DefaultObjectConfigurationAction.java:36)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction$3.run(DefaultObjectConfigurationAction.java:80)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.execute(DefaultObjectConfigurationAction.java:136)
        at org.gradle.api.internal.project.AbstractPluginAware.apply(AbstractPluginAware.java:44)
        at org.gradle.api.internal.project.ProjectScript.apply(ProjectScript.java:34)
        at org.gradle.api.Script$apply$0.callCurrent(Unknown Source)
        at build_84ct78fvs02vr9maz6lpgl5hs.run(/Users/gastonmo/Documents/slate/slate/slate-distribution/build.gradle:5)
        at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:90)
        ... 62 more
Caused by: java.lang.ClassNotFoundException: org.gradle.api.internal.component.Usage
        ... 77 more```

Support for entire folder as build context

Hi,

I would like to use the entire folder containing my dockerfile as the build context, like I would normally do with docker. If I use files "." it seems to work ok, although it ends up sending the context in many different steps.. I just wanted to check if you all had thought about this, and whether I was doing it correctly.

This shows the difference between when I build with gradle and with normal docker.

Lohengrin:docker rmelick$ gradle docker
:docker:dockerClean
:docker:dockerPrepare
:docker:dockerSetup
:docker:docker
Sending build context to Docker daemon 557.1 kB 
Sending build context to Docker daemon 1.114 MB 
Sending build context to Docker daemon 1.671 MB
Sending build context to Docker daemon 2.228 MB                                                              
Sending build context to Docker daemon 2.785 MB                                                              
Sending build context to Docker daemon 3.342 MB                                                              
Sending build context to Docker daemon 3.899 MB                                                              
Sending build context to Docker daemon 4.456 MB                                                              
Sending build context to Docker daemon 5.014 MB                                                              
Sending build context to Docker daemon 5.571 MB                                                             
 Sending build context to Docker daemon 6.128 MB                                                              
Sending build context to Docker daemon 6.576 MB
Step 1 : FROM java:8
 ---> 081ce13c85db
Step 2 : ADD vert.x-2.1.5.zip /opt/vertx/
 ---> Using cache
 ---> 2f8f504d06af
Step 3 : ENV PATH $PATH:/opt/vertx/vert.x-2.1.5/bin
 ---> Using cache
 ---> 18c60e7081e7
Successfully built 18c60e7081e7

BUILD SUCCESSFUL

Total time: 1.223 secs
Lohengrin:docker rmelick$ docker build .
Sending build context to Docker daemon 13.15 MB
Step 1 : FROM java:8
 ---> 081ce13c85db
Step 2 : ADD vert.x-2.1.5.zip /opt/vertx/
 ---> Using cache
 ---> 2f8f504d06af
Step 3 : ENV PATH $PATH:/opt/vertx/vert.x-2.1.5/bin
 ---> Using cache
 ---> 18c60e7081e7
Successfully built 18c60e7081e7
Lohengrin:docker rmelick$ 

Thanks!

JDK 9 - IncompatibleClassChangeError in DockerExtension

Trying to apply the plugin using JDK-9-ea (build 9-ea+144) I get the following exception:

java.lang.IncompatibleClassChangeError: Method java.util.Set.of()Ljava/util/Set; must be InterfaceMethodref constant
        at java_util_Set$of.call(Unknown Source)
        at com.palantir.gradle.docker.DockerExtension.<init>(DockerExtension.groovy:33)
        at com.palantir.gradle.docker.DockerExtension_Decorated.<init>(Unknown Source)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:455)
        at org.gradle.internal.reflect.DirectInstantiator.newInstance(DirectInstantiator.java:42)
        ... 93 more

Gradle 3.2.1
gradle-docker 0.9.2

Cannot copy file into Docker image

Hi

I am trying to build a simple docker image that requires a jar file to be copied from directory build/libs/ (the standard Gradle java plugin artefact output directory), but the docker task is reporting lstat build/libs/myservice.jar: no such file or directory. The file definitely exists at the given location, and using the command line docker build -t x/y . works OK.

Any ideas what I've missed?

Thx

Document dockerPush task

I'd like to be able to use the dockerPush task to push an image that was built using the palantir docker task to a private repository (Sonatype Nexus 3).

From the docs, I can't work out how to use the dockerPush task for pushing to a private repository. Can you document how this task works, along with an example.

Thanks in advance.

Docker-compose plugin can't resolve dependencies for subprojects

I have defined a dependency of type docker project(':sub') which builds a docker image in my docker-compose module. When building the docker-compose project i get the following stacktrace:

* What went wrong:
A problem occurred configuring project ':app'.
> Could not resolve all dependencies for configuration ':app:docker'.
   > Configuration with name 'default' not found.

* Try:
Run with --info or --debug option to get more log output.

* Exception is:
org.gradle.api.ProjectConfigurationException: A problem occurred configuring project ':app'.
        at org.gradle.configuration.project.LifecycleProjectEvaluator.addConfigurationFailure(LifecycleProjectEvaluator.java:79)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.notifyAfterEvaluate(LifecycleProjectEvaluator.java:74)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:61)
        at org.gradle.api.internal.project.AbstractProject.evaluate(AbstractProject.java:532)
        at org.gradle.api.internal.project.AbstractProject.evaluate(AbstractProject.java:93)
        at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:47)
        at org.gradle.configuration.DefaultBuildConfigurer.configure(DefaultBuildConfigurer.java:35)
        at org.gradle.initialization.DefaultGradleLauncher$2.run(DefaultGradleLauncher.java:125)
        at org.gradle.internal.Factories$1.create(Factories.java:22)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:52)
        at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:122)
        at org.gradle.initialization.DefaultGradleLauncher.access$200(DefaultGradleLauncher.java:32)
        at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:99)
        at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:93)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:62)
        at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:93)
        at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:82)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:94)
        at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28)
        at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:43)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:28)
        at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:75)
        at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:45)
        at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:52)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
        at org.gradle.util.Swapper.swap(Swapper.java:38)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.health.DaemonHealthTracker.execute(DaemonHealthTracker.java:40)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:66)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:72)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.health.HintGCAfterBuild.execute(HintGCAfterBuild.java:41)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
        at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:246)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
        at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
Caused by: org.gradle.api.artifacts.ResolveException: Could not resolve all dependencies for configuration ':app:docker'.
        at org.gradle.api.internal.artifacts.ivyservice.ErrorHandlingConfigurationResolver.wrapException(ErrorHandlingConfigurationResolver.java:70)
        at org.gradle.api.internal.artifacts.ivyservice.ErrorHandlingConfigurationResolver.resolve(ErrorHandlingConfigurationResolver.java:45)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.resolveGraphIfRequired(DefaultConfiguration.java:371)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.resolveNow(DefaultConfiguration.java:346)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.getResolvedConfiguration(DefaultConfiguration.java:339)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration_Decorated.getResolvedConfiguration(Unknown Source)
        at org.gradle.api.internal.BeanDynamicObject$MetaClassAdapter.getProperty(BeanDynamicObject.java:166)
        at org.gradle.api.internal.BeanDynamicObject.getProperty(BeanDynamicObject.java:109)
        at org.gradle.api.internal.CompositeDynamicObject.getProperty(CompositeDynamicObject.java:81)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration_Decorated.getProperty(Unknown Source)
        at com.palantir.gradle.docker.DockerComposePlugin$_apply_closure2.doCall(DockerComposePlugin.groovy:41)
        at org.gradle.listener.ClosureBackedMethodInvocationDispatch.dispatch(ClosureBackedMethodInvocationDispatch.java:40)
        at org.gradle.listener.ClosureBackedMethodInvocationDispatch.dispatch(ClosureBackedMethodInvocationDispatch.java:25)
        at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:44)
        at org.gradle.internal.event.BroadcastDispatch.dispatch(BroadcastDispatch.java:79)
        at org.gradle.internal.event.BroadcastDispatch.dispatch(BroadcastDispatch.java:30)
        at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
        at com.sun.proxy.$Proxy10.afterEvaluate(Unknown Source)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.notifyAfterEvaluate(LifecycleProjectEvaluator.java:67)
        ... 52 more
Caused by: org.gradle.api.artifacts.UnknownConfigurationException: Configuration with name 'default' not found.
        at org.gradle.api.internal.artifacts.configurations.DefaultConfigurationContainer.createNotFoundException(DefaultConfigurationContainer.java:92)
        at org.gradle.api.internal.DefaultNamedDomainObjectCollection.getByName(DefaultNamedDomainObjectCollection.java:210)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfigurationContainer.getByName(DefaultConfigurationContainer.java:82)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfigurationContainer.getByName(DefaultConfigurationContainer.java:37)
        at org.gradle.api.internal.artifacts.dependencies.DefaultProjectDependency.getProjectConfiguration(DefaultProjectDependency.java:69)
        at org.gradle.api.internal.artifacts.dependencies.DefaultProjectDependency_Decorated.getProjectConfiguration(Unknown Source)
        at org.gradle.api.internal.artifacts.ivyservice.moduleconverter.dependencies.ProjectIvyDependencyDescriptorFactory.createDependencyDescriptor(ProjectIvyDependencyDescriptorFactory.java:40)
        at org.gradle.api.internal.artifacts.ivyservice.moduleconverter.dependencies.DefaultDependencyDescriptorFactory.createDependencyDescriptor(DefaultDependencyDescriptorFactory.java:35)
        at org.gradle.api.internal.artifacts.ivyservice.moduleconverter.dependencies.DefaultDependenciesToModuleDescriptorConverter.addDependencies(DefaultDependenciesToModuleDescriptorConverter.java:44)
        at org.gradle.api.internal.artifacts.ivyservice.moduleconverter.dependencies.DefaultDependenciesToModuleDescriptorConverter.addDependencyDescriptors(DefaultDependenciesToModuleDescriptorConverter.java:37)
        at org.gradle.api.internal.artifacts.ivyservice.moduleconverter.DefaultConfigurationComponentMetaDataBuilder.addDependencies(DefaultConfigurationComponentMetaDataBuilder.java:51)
        at org.gradle.api.internal.artifacts.ivyservice.moduleconverter.DefaultConfigurationComponentMetaDataBuilder.addConfigurations(DefaultConfigurationComponentMetaDataBuilder.java:39)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.toRootComponentMetaData(DefaultConfiguration.java:554)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.DefaultArtifactDependencyResolver$DefaultResolveContextToComponentResolver.resolve(DefaultArtifactDependencyResolver.java:140)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.DependencyGraphBuilder.resolve(DependencyGraphBuilder.java:70)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.DefaultArtifactDependencyResolver$1.execute(DefaultArtifactDependencyResolver.java:88)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.DefaultArtifactDependencyResolver$1.execute(DefaultArtifactDependencyResolver.java:78)
        at org.gradle.internal.Transformers$4.transform(Transformers.java:169)
        at org.gradle.api.internal.artifacts.ivyservice.DefaultIvyContextManager.withIvy(DefaultIvyContextManager.java:61)
        at org.gradle.api.internal.artifacts.ivyservice.DefaultIvyContextManager.withIvy(DefaultIvyContextManager.java:39)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.DefaultArtifactDependencyResolver.resolve(DefaultArtifactDependencyResolver.java:78)
        at org.gradle.api.internal.artifacts.ivyservice.CacheLockingArtifactDependencyResolver$1.run(CacheLockingArtifactDependencyResolver.java:41)
        at org.gradle.internal.Factories$1.create(Factories.java:22)
        at org.gradle.cache.internal.DefaultCacheAccess.useCache(DefaultCacheAccess.java:192)
        at org.gradle.cache.internal.DefaultCacheAccess.useCache(DefaultCacheAccess.java:175)
        at org.gradle.cache.internal.DefaultPersistentDirectoryStore.useCache(DefaultPersistentDirectoryStore.java:106)
        at org.gradle.cache.internal.DefaultCacheFactory$ReferenceTrackingCache.useCache(DefaultCacheFactory.java:187)
        at org.gradle.api.internal.artifacts.ivyservice.DefaultCacheLockingManager.useCache(DefaultCacheLockingManager.java:64)
        at org.gradle.api.internal.artifacts.ivyservice.CacheLockingArtifactDependencyResolver.resolve(CacheLockingArtifactDependencyResolver.java:39)
        at org.gradle.api.internal.artifacts.ivyservice.DefaultConfigurationResolver.resolve(DefaultConfigurationResolver.java:91)
        at org.gradle.api.internal.artifacts.ivyservice.SelfResolvingDependencyConfigurationResolver.resolve(SelfResolvingDependencyConfigurationResolver.java:40)
        at org.gradle.api.internal.artifacts.ivyservice.ShortCircuitEmptyConfigurationResolver.resolve(ShortCircuitEmptyConfigurationResolver.java:52)
        at org.gradle.api.internal.artifacts.ivyservice.ErrorHandlingConfigurationResolver.resolve(ErrorHandlingConfigurationResolver.java:43)
        ... 69 more

I can see in the debugger that at DockerComposePlugin.groovy:41 the dependencies for the docker configuration exist as defined but not of type docker.

Is it possible that you forgot to create the artifacts in the PalantirDockerPlugin around line 65? There only the zip artifact is created. So gradle tries to define the dependencies with some default?

'files' parameters is verified too early for a dynamically generated Docker context

I'm trying to create a Docker context that only includes the output TAR from the distribution plugin so I've configured it as...

docker {
    dependsOn distTar
    name "${project.group}/${project.name}:${project.version}"
    tags "latest"
    buildArgs([BUILD_VERSION: project.version])
    files distTar.archivePath.absolutePath, 'Dockerfile'
}

This configuration is failing, however, because the Docker plugin is checking for the existence of this file during project configuration, long before it get created.

This isn't a huge issue but without specifying the 'files' parameter, the entire src/ directory plus build.gradle, gradle.properties etc. are also getting copied unnecessarily into the context.

Ability to easily push all tags for an image

It would be great if we could easily push all tags for an image. The dockerTag task is nice for tagging them all, but currently dockerPush only pushes the main named image, and does not push those other tags.

Files listed in 'files' are eagerly checked for existence

My Dockerfile adds an artifact produced by the 'dist' task and so I have a task dependency on dist in the docker plugin configuration. However when I add that file to the 'files' property, Gradle throws and error saying the file doesn't exist before attempting to build anything. The file will exist once the dist task has completed.

Not working with gradle 3.3

Configuration used from https://plugins.gradle.org/plugin/com.palantir.docker

buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "gradle.plugin.com.palantir.gradle.docker:gradle-docker:0.12.0"
}
}

apply plugin: "com.palantir.docker"

Error Message:
17:56:25.999 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]
17:56:25.999 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] FAILURE: Build failed with an exception.
17:56:26.001 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]
17:56:26.001 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] * What went wrong:
17:56:26.001 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] org/gradle/api/internal/component/UsageContext
17:56:26.002 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] > org.gradle.api.internal.component.UsageContext
17:56:26.002 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]
17:56:26.002 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] * Try:
17:56:26.002 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] Run with --stacktrace option to get the stack trace.
17:56:26.002 [LIFECYCLE] [org.gradle.internal.buildevents.BuildResultLogger]
17:56:26.002 [LIFECYCLE] [org.gradle.internal.buildevents.BuildResultLogger] BUILD FAILED
17:56:26.002 [LIFECYCLE] [org.gradle.internal.buildevents.BuildResultLogger]
17:56:26.002 [LIFECYCLE] [org.gradle.internal.buildevents.BuildResultLogger] Total time: 2.289 secs

Add `dockerLogin` task

Add a block to the docker config block that accepts multiple docker sites and credentials, e.g.:

docker {
    login {
        'hub.docker.com' {
            username System.env.USERNAME
            password System.env.PASSWORD
        }        
    }
...

docker and dockerPush must depend on `dockerLogin.

Conflicting Options --rm -d

When trying to use this configuration

dockerRun {
    name 'api_container'
    image "myimage:$version"
    daemonize true
    clean true
    ports '9080:8080'
    env (['couchbase.bootstrapHosts': couchbaseHost])
} 

It works correctly on mac using docker for mac with docker version Docker version 1.13.0-rc2, build 1f9b3ef but when I run the same script on my ci server running ubuntu 16.04 and docker version Docker version 1.12.3, build 6b644ec it fails.

The generated command is

docker run -d --rm -p 9080:8080 -e couchbase.bootstrapHosts=172.17.0.3 --name api_container myimage:0.1-ff35b7d

docker disregards dependsOn clause for sourcing files

I have explicitly defined the file that needs to be copied over to the build/docker directory using the 'file' clause.

Yet the file is supposed to be generated by the previous task, with the dependency defined by dependsOn clause:

docker { name "${dockerImageName}" dockerfile 'src/main/docker/Dockerfile' dependsOn tasks.fatJar files "files "build/packed/${jarFullName}"" }

I have a suspicion that the file is being checked prior the fatJar running. I get the following error:

'build/packed/fatJarName-2.1.3.jar' does not exist.

Do I miss something here? Wouldn't it be logical to build the file list after the dependsOn tasks have completed?

Indeed, when gradle runs the order seems to be:

:dockerfileZip
:compileJava
:processResources
:classes
:findMainClass
:jar
:bootRepackage
:fatJar
:dockerPrepare
:docker

Notice the dockerfileZip being the first. Wouldn't it be logical to move dockerfileZip to be placed immediately before dockerPrepare?

New feature: include a dockerRemoveImage to PanaltirDockerPlugin

dockerRemoveImage is the only task missing the build-run-stop-remove life-cycle. Please consider adding this task, which simplifies testing images that we know are temporary so we want to discard them immediately.

This is what I have in my build script to solve this issue:

task dockerRemoveImage(type:Exec) {
group = 'Docker'
description = 'Remove Docker image.'
dependsOn dockerSetup
shouldRunAfter project.tasks.findByName('docker'),
project.tasks.findByName('dockerRun'),
dockerStop,
dockerRemoveContainer
commandLine 'docker', 'rmi', project.name
}

Of course instead of using project.name as the image name, it should come from DockerExtension name property

CircleCI bug when calling docker rmi on docker image built from Dockerfile with ADD command

When attempting to remove a Docker image that was built from a Dockerfile with the ADD command, docker rmi fails on CircleCI with an error similar to the following:

Failed to remove image (id3): Error response from daemon: Failed to destroy btrfs snapshot /var/lib/docker/btrfs/subvolumes for 72fdc6cc5b827ee1f352a506faaef06e7fddcffcb954aeeaeed575df97590958: operation not permitted

Relevant version info for repro:

Client:
 Version:      1.10.0-circleci
 API version:  1.22
 Go version:   go1.5.3
 Git commit:   543ec7b-unsupported
 Built:        Tue Feb 16 17:11:12 2016
 OS/Arch:      linux/amd64

Server:
 Version:      1.10.0-circleci
 API version:  1.22
 Go version:   go1.5.3
 Git commit:   543ec7b-unsupported
 Built:        Tue Feb 16 17:11:12 2016
 OS/Arch:      linux/amd64

Tags Don't Work

Using this build.gradle:

buildscript {
    repositories {
    jcenter()
        mavenCentral()
    }
}

plugins {
    id "org.springframework.boot" version "1.5.1.RELEASE"
    id "com.palantir.docker" version "0.12.0"
}

apply plugin: 'java'

project.version = '0.1.0'

jar {
    baseName = 'test'
    archiveName = 'test.jar'
}

docker {
    name 'test-account/repo1'
    tags 'test','0.1.0'
    dockerfile 'src/main/docker/Dockerfile'
    dependsOn assemble
    files jar
}

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    compile('org.springframework.boot:spring-boot-starter-web')
    compile('org.springframework.boot:spring-boot-starter-actuator')
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

I can successfully build and create the Docker image, but it is not tagged as defined in the build.gradle.

$ gradle clean docker
:clean
:dockerfileZip
:compileJava
:processResources
:classes
:findMainClass
:jar
:bootRepackage
:assemble
:dockerClean UP-TO-DATE
:dockerPrepare
:docker

BUILD SUCCESSFUL

Total time: 20.099 secs

$ docker images
REPOSITORY                   TAG                 IMAGE ID            CREATED             SIZE
test-account/repo1           latest              e4442c2dbd93        4 seconds ago       181 MB

Fails on Docker for Windows

If files is unspecified on Windows the following error ocurrs.

FAILURE: Build failed with an exception.

* What went wrong:
Failed to capture snapshot of input files for task 'dockerPrepare' property 'source' during up-to-date check.
> Failed to create MD5 hash for file 'C:\Users\kspring\Documents\repos\blur-re\.gradle\3.1\taskArtifacts\cache.properties.lock'.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

This issue which is isolated to Windows stems from trying to copy the .gradle directory.

I have found several resolutions

  1. Update extension to ignore the .gradle directory when copying files
  2. User specifies the files to be exactly what one needs. This results in a problem simliar to what was identified in issue #42. In my environment, the workaround does not function. I am using Spring Boot and the bootRepackage task output is not copied as stated in #42. This leads me to the next resolution.
  3. Don't check for file existence during the task configuration phase. Wait until the task actually runs before looking for the files on disk. This would allow the dependsOn tasks to generate the needed artifacts.
  4. Instead of option 3, allow for doFirst closure so one can set the files in there.

How can I run several containers in a single build?

Thanks for the plugin!

I'm wondering whether it is possible to define tasks that each runs a different container? The problem is that there is no such class like DockerRunTask that could be extended, instead tasks like dockerRun are created in DockerRunPlugin

I was trying the following approach:

task runComposer() {
    dockerRun {
        name 'my-container'
        image 'composer/composer:php5'
        volumes '.': '/app'
        daemonize false
        command 'install'
    }

    dependsOn   "dockerRun"
}

task runHelloWorld() {
    dockerRun {
        name 'other-container'
        image 'hello-world'
        volumes '.': '/app'
        daemonize false
    }

    dependsOn   "dockerRun"
}

It seems though it isn't the valid approach as both tasks are configuring the same instance of dockerRun task, effectively overwriting the dockerRun configuration.

Any ideas?

Thanks!

Change template name to docker-compose.template.yml

Could we rename the docker-compose.yml.template template default filename to docker-compose.template.yml?

IDEs won't do yaml syntax highlighting on a yaml file with a ".template" extension.

I know I can use the following block:

dockerCompose {
    template 'docker-compose.template.yml'
}

But, I would prefer a better default to avoid adding these lines to my build.gradle

Gradle 3 Support For Docker-Run

When trying to use docker-run under gradle 3 I get the error

No service of type StyledTextOutputFactory available in ProjectScopeServices.

Google suggests this is a compatibility issue with gradle 3.

Trying to use build output of other tasks fails a clean build

I am attempting to add some of the built artifacts to my docker image, by using the files option when configuring docker. The modZip task is the task that builds the zip into the build/libs folder.

docker {
 ...
  dockerfile 'docker/Dockerfile'
  dependsOn modZip
  files 'docker/', 'build/libs/', 'conf.json'
}

However, when I attempt to build the project for the first time, I get the following error


FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring root project 
> file 'build/libs/' does not exist.

* Try:
Run with --stacktrace option to get the stack trace. Run with --debug option to get more log output.

BUILD FAILED

Total time: 2.089 secs

The full stacktrace looks like

* What went wrong:
A problem occurred configuring root project 
> file 'build/libs/' does not exist.

* Try:
Run with --info or --debug option to get more log output.

* Exception is:
org.gradle.api.ProjectConfigurationException: A problem occurred configuring root project .
    at org.gradle.configuration.project.LifecycleProjectEvaluator.addConfigurationFailure(LifecycleProjectEvaluator.java:79)
    at org.gradle.configuration.project.LifecycleProjectEvaluator.notifyAfterEvaluate(LifecycleProjectEvaluator.java:74)
    at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:61)
    at org.gradle.api.internal.project.AbstractProject.evaluate(AbstractProject.java:532)
    at org.gradle.api.internal.project.AbstractProject.evaluate(AbstractProject.java:93)
    at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:42)
    at org.gradle.configuration.DefaultBuildConfigurer.configure(DefaultBuildConfigurer.java:35)
    at org.gradle.initialization.DefaultGradleLauncher$2.run(DefaultGradleLauncher.java:125)
    at org.gradle.internal.Factories$1.create(Factories.java:22)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:52)
    at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:122)
    at org.gradle.initialization.DefaultGradleLauncher.access$200(DefaultGradleLauncher.java:32)
    at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:99)
    at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:93)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:62)
    at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:93)
    at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:82)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:94)
    at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28)
    at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:43)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:28)
    at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:75)
    at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:45)
    at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:52)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
    at org.gradle.util.Swapper.swap(Swapper.java:38)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.health.DaemonHealthTracker.execute(DaemonHealthTracker.java:47)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:66)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:72)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.health.HintGCAfterBuild.execute(HintGCAfterBuild.java:41)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
    at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:246)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
    at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
Caused by: java.lang.IllegalArgumentException: file 'build/libs/' does not exist.
    at com.google.common.base.Preconditions.checkArgument(Preconditions.java:145)
    at com.palantir.gradle.docker.DockerExtension.resolvePathsAndValidate(DockerExtension.groovy:115)
    at com.palantir.gradle.docker.DockerExtension$resolvePathsAndValidate.call(Unknown Source)
    at com.palantir.gradle.docker.PalantirDockerPlugin$_apply_closure6.doCall(PalantirDockerPlugin.groovy:73)
    at org.gradle.listener.ClosureBackedMethodInvocationDispatch.dispatch(ClosureBackedMethodInvocationDispatch.java:40)
    at org.gradle.listener.ClosureBackedMethodInvocationDispatch.dispatch(ClosureBackedMethodInvocationDispatch.java:25)
    at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:44)
    at org.gradle.internal.event.BroadcastDispatch.dispatch(BroadcastDispatch.java:79)
    at org.gradle.internal.event.BroadcastDispatch.dispatch(BroadcastDispatch.java:30)
    at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
    at com.sun.proxy.$Proxy10.afterEvaluate(Unknown Source)
    at org.gradle.configuration.project.LifecycleProjectEvaluator.notifyAfterEvaluate(LifecycleProjectEvaluator.java:67)
    ... 52 more

Is there a better way to reference files from other build steps?

dockerRemoveContainer should run after dockerStop

If I run dockerStop and dockerRemoveContainer on the same command, it fails. If I add the following line to my build script:

dockerRemoveContainer.shouldRunAfter dockerStop

Everything works as expected. Adding shouldRunAfter dockerStop to the definition of dockerRemoveContainer should fix this issue.

Rename Docker Run Extension

I had followed the info in the docs and was getting a really confusing error.

Caused by: org.gradle.internal.typeconversion.UnsupportedNotationException: Cannot convert com.palantir.gradle.docker.DockerRunExtension_Decorated@3d449b13 to a task.

this was because the configuration block

dockerRun {
    name 'api_container'
    image "myImage:image:$version"
    daemonize true
    env 'couchbase.bootstrapHosts': couchbaseHost
}

has the same name as the task so task myTask(dependsOn: dockerRun) results in the above error. You need to explicitly reference the task task myTask(dependsOn: tasks.dockerRun) this is not obvious.

ADD build/distributions/*.tar (retain folder structure using files or include from project.buildDir?)

Hi, I really like the approach of this plugin but have encountered a problem which prohibits me form using it:

I have an artifact that is created by task:distTar and is located in build/distributions. From viewing the source code I can see that when no files argument is provided, the plugin will include all files except the ones in the build directory. This becomes problematic because my artifact is actually located in the build folder. And when I try to explicitly include my artifact, the path is not retained and the file is instead placed in the root of the build/docker sub-directory.

This means that I would either have to relocate my artifact manually before running this plugin, or change my Dockerfile to look for the file in the root instead of in the build folder, neither of which I want to do.

I have two suggestions to solve this problem:

  1. optionally keep the folder structure when explicitly including files using the files argument. (preferred)
  2. optionally include files from build (good enough)

(I also tried to explicitly include "everything" but that seems to fail due to a stack overflow when creating the path, probably a bug. Steps to reproduce: files "${projectDir}" or files '.').

Thanks a lot!

/Johannes

dockerTag task defined in afterEvaluate

Which means it's very hard to depend on in the task graph. Desired behaviour: task is defined outside of the afterEvaluate closure, and only wired up in afterEvaluate block.

FR: ability to re-use the variables defined in the gradle project

Would like to be able to reference gradle project variables. Something like that:

version: '2'
services:
  my-service:
    container_name: container
    image: "my/image:{{version}}"

Currently I get

> Failed to resolve Docker dependencies declared in project/docker-compose.yml.template: [{{version}}]. Known dependencies: {}

Need more examples in docs (or missing features)

It really seems like the doc for this doesn't have a lot of information for real use cases, at least for mine.

I'm working on issues described in this posting. I don't see the best way to get access to the dependencies to include in the image.

It seems reasonable to assume that many people are going to use this plugin to build an image containing some of the other artifacts built in a multi-project build. It would help if examples showed the best way to make that happen.

Docs: dependsOn to files

I recently upgraded to the latest version of the plugin. I noted the move from dependsOn to files.

I am using spring boot in a multi project.

My config looks like

docker {
    name "app:${project.version}"
    dependsOn tasks.jar, tasks.bootRepackage
}

This previously copied the src/main/resources content across (and maintained the directory structure src/main/resources/...).

My config now looks like below, with everything below src/main/resources in the build/docker directory, ideally I'd like them in build/docker/src/main/resources/ ...

docker {
    name "app:${project.version}"
    files tasks.jar.outputs, tasks.bootRepackage.outputs, 'src/main/resources'
}

Is there a better solution for getting the src/main/resources across and maintaining the directory structure?

Thanks.

files not added to docker context

Using the "files" method of the docker closure does not seem to have any effect.

I am trying to add a file like:

docker {
  name "myImage:${version}"
  files "myFile.txt"
}

In a Dockerfile that includes:

ADD myFile.txt /tmp/

but when running it I get the error:

Step 7 : ADD myFile.txt /tmp/
myFile.txt: no such file or directory
:myProject:docker FAILED

If I run dockerPrepare, I can see that while the Dockerfile appears in the build/ directory of the project, myFile.txt is not there.

Better error in DockerComposePlugin

Hey guys,

Minor feedback: would be nice to have a better error when running ./gradlew generateDockerCompose than:

  • What went wrong:
    Execution failed for task ':generateDockerCompose'.

Could not copy file...

When the underlying stack trace is:

Caused by: java.lang.IllegalStateException: Failed to resolve Docker dependencies declared in docker-compose.yml.template: [{{foo:bar}]โ€ฆ

I'd look into contributing this but haven't figured out how to contribute to gradle libraries yet, so just wanted to capture as an issue if we aren't tracking. Thanks!

Rick

Still confused about how to actually use this to build an image

It still feels like there are many missing pieces in this doc. The doc for "dockerPrepare" says barely anything. I can't tell exactly what it's supposed to be doing. I can sort of see the result, but it's missing the files I added, so the final Docker build fails. I'm sure I'm just missing some details that are probably assumptions that I'm not aware of.

My application is a multiproject build, with two WAR projects along with the subproject to build the image. The image subproject depends on the two projects, and a JDBC jar, all three of which I try to add to the context so the Dockerfile can reference them.

The following is the entire build.gradle for the image project:
plugins { id 'com.palantir.docker' version '0.9.0' } apply plugin: 'java' List<String> fileList = ["ordersService.war", "ordersGUI.war", "ojbdc6.jar"].each { "$buildDir/dependencies/" + it } docker { name 'ssorderprocessingdashboard' dockerfile 'src/docker/Dockerfile' files fileList.toArray() } dependencies { runtime project(":ordersService") runtime project(":ordersGUI") runtime "oracle:ojdbc6:11.2.0.3" } task copyDependencies << { configurations.runtime.setTransitive(false).resolvedConfiguration.resolvedArtifacts .each { artifact -> project.copy { from artifact.file into "${buildDir}/dependencies" rename { "${artifact.name}.${artifact.extension}" } } } } build.dependsOn copyDependencies

I haven't yet set task dependencies so the "docker" task will run on build (as that didn't even work, but I'll address that later). For now, I just run the "build" task on the subproject and then the "docker" task on a separate command line.

I verified that after "build", the "${buildDir}/dependencies" dir has my three artifacts properly named.

If it helps, this is my entire Dockerfile:
`FROM tomee:8-jdk-7.0.0-webprofile

ENV SERVICE_HOST_PORT = localhost:8080
ENV DB_HOST = xx
ENV DB_PORT xx
ENV DB_SID xx
ENV DB_USER xx
ENV DB_PASSWORD xx
ENV TOMEE_HOME /usr/local/tomee
ENV env dev

ARG tzoffset

ADD ojdbc6.jar ${TOMEE_HOME}/lib

ADD ordersService.war ${TOMEE_HOME}/webapps/
ADD ordersGUI.war ${TOMEE_HOME}/webapps/

Disable CXF in cxf.properties and cxf-rs.properties.

ADD cxf.properties ${TOMEE_HOME}/conf
ADD cxf-rs.properties ${TOMEE_HOME}/conf

Change host:port that GUI is using to reach the REST service.

If SERVICE_HOST_PORT is set, use that, otherwise use

localhost:8080.

Add DataSource definition to tomee.xml.

ADD tomee.xml.excerpt ${TOMEE_HOME}
ADD system.properties.excerpt ${TOMEE_HOME}
ADD adjustTomEEConfig.sh ${TOMEE_HOME}

Install gettext for envsubst.

ADD aptconf.txt /etc/apt/apt.conf
RUN apt-get update
RUN apt-get install -y gettext

CMD ${TOMEE_HOME}/adjustTomEEConfig.sh $tzoffset; ${TOMEE_HOME}/bin/catalina.sh run`

When I run the "docker" task, this is what I see:
`:ordersImage:dockerClean
:ordersImage:dockerPrepare
:ordersImage:docker
Sending build context to Docker daemon 751 MB
Step 1 : FROM tomee:8-jdk-7.0.0-webprofile
---> 5a2d656682a9
...
Step 11 : ADD ojdbc6.jar ${TOMEE_HOME}/lib
lstat ojdbc6.jar: no such file or directory
:ordersImage:docker FAILED

FAILURE: Build failed with an exception.`

I am just guessing that "${buildDir}/docker" is what "dockerPrepare" produces. The doc doesn't say, and it doesn't say anything about how I can control that, but I think it's a reasonable guess that's what it produces. This directory does not include the "build" directory, or "build/dependencies", which is where the files are stored. I explicitly said to include the files from that directory, so I would assume that "dockerPrepare" would respect that.

I could use some help here.

Feature Request: Support for --build-arg in docker task

I'm attempting to build a docker image that contains a versioned tar (kiwiCloud-6.0.0.0-SNAPSHOT.tar) file that is produced by a different part of my build.

build.gradle file

plugins {
    id 'com.palantir.docker' version '0.7.0'
}

docker {
    name "docker.com/rmelick/cloud/api:$version"
    dependsOn tasks.getByPath(':distTar')
}

Dockerfile

FROM java:8

ADD kiwiCloud-* /

I would like to be able to pass the version parameter into my Dockerfile as a build-arg. This would let me remove the wildcard from the ADD command, and would also let me use the version when referencing the contents of the tar (the script I want to use for ENTRYPOINT is inside the tar).

Cannot apply docker-compose in a sub-project

The generateDockerCompose task resolves dependencies from the current project, so if you're applying the plugin in a Gradle sub-project, the task will fail if you have your dependencies defined in your root build.gradle. See: https://github.com/palantir/gradle-docker/blob/develop/src/main/groovy/com/palantir/gradle/docker/DockerComposePlugin.groovy#L41. Is this intended behavior? If not, perhaps we can change it to also include the root project's dependencies.

Docker-compose resolves dependencies during configuration time

While generateDockerCompose does need to use the dependencies from the docker configuration for further operation, I think it can do so during the task execution stage rather than project configuration stage. This accelerates project evaluation during the (common) case where generateDockerCompose is not being executed.

able to run docker-compose files

would it be possible to add the ability to run a docker-compose file from this gradle plugin, similar to the docker-run plugin. it could also depend on the generating the YAML file from the template, etc.

Define Tags Based on Another Task

I use another task (id "com.zoltu.git-versioning" version "3.0.2") to set the project.version dynamically based on Git tags.

But it doesn't set the project.version until after the first phase of Gradle processing. So if I set the tags for id "com.palantir.docker" version "0.12.0" as such:

docker {
    tags project.version
}

I end up with tagging the image with unspecified.

Is there a way to set the tags after Gradle's first phase?

I suspect that I need to add a doFirst closure such as this:

dockerPrepare.doFirst {
     println "dockerPrepare.doFirst, project.version: " + project.version
}

but how do I update planitir's tags property?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.