gradle-docker
gradle-docker copied to clipboard
dockerPush doesn't generate (and thus push) all Tags
I have the following config:
docker {
name 'my-company/my-image'
tags project.version, 'latest'
dockerfile file('src/main/docker/Dockerfile')
dependsOn assemble
files jar
}
If I remove all images from my local machine other then the base image and then do:
$ gradle clean dockerPush
> Task :rest-service:dockerPush
The push refers to a repository [docker.io/my-company/my-image]
07cb7e265fa0: Preparing
762429e05518: Preparing
2be465c0fdf6: Preparing
5bef08742407: Preparing
2be465c0fdf6: Layer already exists
5bef08742407: Layer already exists
762429e05518: Layer already exists
07cb7e265fa0: Pushed
latest: digest: sha256:09ae39c3379061413cc450148fdb32baa2b07616fed5341df542595b3eb08b5f size: 1154
BUILD SUCCESSFUL in 10s
11 actionable tasks: 8 executed, 3 up-to-date
Notice however that only an image with the latest tag is created, so naturally that was all that was pushed:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-company/my-image latest c588bc51ad2e 7 seconds ago 81.4MB
openjdk 8u131-jre-alpine e2f6fe2dacef 5 weeks ago 81.4MB
To continue the example, I remove the image just created as such:
$ docker rmi c588bc51ad2e
Untagged: my-company/my-image:latest
Untagged: my-company/my-image@sha256:09ae39c3379061413cc450148fdb32baa2b07616fed5341df542595b3eb08b5f
Deleted: sha256:c588bc51ad2e5019176b09377fa9b15caa92216f6540dfb880c914dbafb69e47
Deleted: sha256:63d4d33b985b3ef47804d7e25cea23d91f4bef88a69168da2b54721aadd5eb97
Deleted: sha256:595c32029464585e6871fc32d075f12e4a175bae5c9d016c9fa9e6fc8975168c
Deleted: sha256:46e42747ee2fd820e49b90be14f066bdee60d589ca914eaf937df5aec811e037
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
openjdk 8u131-jre-alpine e2f6fe2dacef 5 weeks ago 81.4MB
And then run dockerTag first I get both tags and then dockerPush both are then pushed as shown here:
$ gradle clean dockerTag
BUILD SUCCESSFUL in 2s
12 actionable tasks: 9 executed, 3 up-to-date
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-company/my-image 0.1.24 3b1e1562402f Less than a second ago 81.4MB
my-company/my-image latest 3b1e1562402f Less than a second ago 81.4MB
openjdk 8u131-jre-alpine e2f6fe2dacef 5 weeks ago 81.4MB
$ gradle dockerPush
> Task :rest-service:dockerPush
The push refers to a repository [docker.io/my-company/my-image]
e13e5448aea4: Preparing
762429e05518: Preparing
2be465c0fdf6: Preparing
5bef08742407: Preparing
2be465c0fdf6: Layer already exists
5bef08742407: Layer already exists
762429e05518: Layer already exists
e13e5448aea4: Pushed
0.1.24: digest: sha256:129ecb7f1ed98f799ea44849b5a72beb79064d15f8484e2dcb37344a105df9a7 size: 1154
e13e5448aea4: Preparing
762429e05518: Preparing
2be465c0fdf6: Preparing
5bef08742407: Preparing
2be465c0fdf6: Layer already exists
5bef08742407: Layer already exists
762429e05518: Layer already exists
e13e5448aea4: Layer already exists
latest: digest: sha256:129ecb7f1ed98f799ea44849b5a72beb79064d15f8484e2dcb37344a105df9a7 size: 1154
BUILD SUCCESSFUL in 8s
8 actionable tasks: 5 executed, 3 up-to-date
Is there a trick to getting dockerPush to generate both tags, so that you can push them in one command?
In the same Gradle file as your Docker block:
tasks.dockerPush.dependsOn(tasks.dockerTag)
Oh, I see we need to setup the dependencies manually. It felt like a bug given that dockerTag acted differently then dockerPush in terms of what it generated.
With tasks.dockerPush.dependsOn { tasks.dockerTag }, I am able to get it to do the same thing, however IntelliJ warns me that the calls are ambiguous. Is there any way around that?
It looks like declaring the dependency as suggested by @markelliot does not work (see https://github.com/palantir/gradle-docker/issues/151):
tasks.dockerPush.dependsOn(tasks.dockerTag)
Error:
> Could not get unknown property 'dockerTag' for task set of type org.gradle.api.internal.tasks.DefaultTaskContainer.
The only way to get it to work was with @pluttrell syntax using a closure:
tasks.dockerPush.dependsOn { tasks.dockerTag }
Why is that? Is the dockerTag task dynamically added after project configuration?
Also, is there any plan to make this dependency built-in? I believe most people would like to have all their tags pushed.
The reason for the need for the closure is simple: The dockerTag task is only created in 'afterEvaluate', so it's not available during buildscript evaluation. Since closures are evaluated lazily, this closure works:
tasks.dockerPush.dependsOn { tasks.dockerTag }
There are two issues I see that both should be resolved IMHO:
-
have dockerPush depend on all dockerPushXYZ tasks that are created in afterEvaluate automatically. Right now dockerPush doesn't depend on any of the dockerPushXYZ tasks, and I think that's a bug.
-
have dockerTag always be created when the plugin is applied, instead of 'afterEvaluate'. This has the consequence of having an empty task that does nothing if no other Tag tasks are defined, but in gradle we already have a bunch of examples for the same situation (just think about the processResources task in the java plugin, it responds with 'NO-SOURCE' and that's it). You could use 'SKIPPED' if there's no tags defined. SKIPPED is achievable with an 'onlyIf' condition that could depend on whether any other dockerTagXYZ tasks got created or not.
It seems like #177 does almost exactly those things, except for the 'onlyIf' condition
- This isn't quite right, using
docker push <name>without a tag will push all tags. So I don't think we need/want to set up a dependency on the individual push tasks. - Agree that we should just always create the
dockerTagtask.