Hi,
I use the docker-maven-plugin to generate a docker image from a Gitlab CI job. To achieve this I run maven inside a docker image. This docker image needs to access docker to build the image.
To avoid Docker-In-Docker (security) problems, I would like to use Kaniko as described here: https://docs.gitlab.com/ee/ci/docker/using_kaniko.html
With this approach, I expect the docker-maven-plugin to create the DockerFile, but not to call the docker server to build the image. In fact, a second Gitlab job dedicated to Kaniko will build the image after.
The plugin configuration does not support this feature: there is no parameter dedicated to build the DockerFile without building the image itself.
I successfully achieved it patching the class named DockerAccessWithHcClient, creating a new protocol named "stub" as an alternative to unix/npipe to bypass docker server calls (see the attached file : DockerAccessWithHcClient.zip).
It would be great if this feature could be integrated to the plugin. I would greatly appreciate to discuss on this here.
Thanks,
Ben.
@Beennnn : Sounds interesting, Could you please create a PR to move this discussion forward?
I think this could be a valid use case (although many people these days goes the other way round, by providing a Dockerfile to d-m-p instead of using the XML or properties configuration). I think this could be a either a property of the BuildMojo itself or even a new Mojo (we already have a 'SaveMojo', but that for a different task), so that it doesn't even call out to DockerAccess but just copies the tar-archive to a local directory.
Maybe an option for BuildMojo (like saveBuildArchive=<path-to-tar> would help, and together with skipBuild would prevent the build but save the tar).
Wdyt ?
I use it from fabric8-maven-plugin as part of Kubernetes files generation. I want to be able to use it from this context, that's why I suggest to use of an environment variable. I know that with this approach I can set it from the baseUrl with -Ddocker.host=... option as done for the other protocols.
It could be even better to use another variable like -Ddocker.stub=true allowing to bypass creation without the need to change the docker.host value.
Extracting to a new Mojo would require an extra work to integrate it with f8-m-p or other usages so I do not think it is to be recommended.
Defining the path-to-tar could be also useful, but I think it could be considered as a next step additional feature, not directly related to this one. For my usage, It don't need it, so I would let other users argue for it.
Wdyt ?
I want to be able to use it from this context, that's why I suggest to use of an environment variable. I know that with this approach I can set it from the baseUrl with -Ddocker.host=... option as done for the other protocols.
You mean _maven property_ (or _system property_), right ? This is what I suggest with adding an extra configuration option (which can be also refelted as maven property for -D usage)
My idea was that you can just use
mvn docker:build -Ddocker.saveBuildArchive=target/docker-build.tar -Ddocker.skip.build
which would skip the actual build but stores the archive in a file target/docker-build.tar. This option would then both specify the target path (otherwise it's just buried in some deeper build directory) and trigger the generation of the archive. The only problem could be that 'skip.build' is already used for skipping the BuildMojo all together. However, we could add a 'docker.skip.build.image' for a more fine granular specification that only the actual image generation should be prevented.
Thanks @rhuss
It looks perfect 馃憤 . The option name 'docker.skip.build.image' really match for me.
So the command line could be :
mvn docker:build -Ddocker.saveBuildArchive=target/docker-build.tar -Ddocker.skip.build.image
How can we go next ?
@Beennnn Would be awesome if this feature was integrated in the docker-maven-plugin !
Did you create the Pull Request already ?
Being able to build docker image without the need of a Docker serivce running would prevent Dind in CI or the necessity of a Shell Runner with java installed to build my images!
@radamanth I have not created the pull request already. I was expecting @rhuss to ask for it or for someone from the docker team maybe to work on it.
@Beennnn I just thought about (also in the context of #1208) it, and I think we should move that functionality to docker:save instead of docker:build, like in
mvn docker:save -Ddocker.save.file=target/docker.build.tar -Ddocker.save.mode=local
with the new configuration property saveMode which can take the values daemon (for reaching out to the docker daemon) or local (which actually only creates the build archive).
In docker:build we then would remove docker.saveBuildArchive property.
That way we would have a positive implementation of this use case and not a negative one (i.e. we are telling what to do and not what to do not (like skipping the build). From a UX perspective this looks better I think.
wdyt ?
Thanks @rhuss.
Adding a new goal will be more readable by a user of the docker plugin, but I鈥檓 not sure it would me more usable.
As I explained in https://github.com/fabric8io/docker-maven-plugin/issues/1197#issuecomment-481873582 I want to use it from fabric8-maven-plugin as an option in the build command, to be able to disable image generation in a docker environment.
From this point of view, disabling the image generation is just an option to limit the build to the dockerfile.
Moving it to a new goal would require more work from the caller to call either build or save depending on an option. This work, I expect it to be provided by the docker plugin.
Consequently, it would require a change in the fabric8 Maven plugin, and all user existing scripts already calling the docker plugin, instead if simply propagating a maven property.
To match all the point of views, maybe we could provide both : an option in the build command for those who want to limit the build, and a new save target for those who never need to build the image with the plugin.
Adding a new goal will be more readable by a user of the docker plugin, but I鈥檓 not sure it would me more usable.
We already have a docker:save I just would expand on this.
As I explained in #1197 (comment) I want to use it from fabric8-maven-plugin as an option in the build command, to be able to disable image generation in a docker environment.
I see, as f-m-p only inherits the BuildMojo from d-m-p, moving this to a SaveMojo wouldn't help you much.
To match all the point of views, maybe we could provide both : an option in the build command for those who want to limit the build, and a new save target for those who never need to build the image with the plugin.
I agree, let's do it this way. It's then just that you can't specify the location for the build archive for docker:build (so its always at a fixed place below target/).
If you are fine with that, I will open a new issue for the docker:save feature and we add docker.skip.build.image to the BuildMojo for this issue.
Yes 馃憤Let's do it this way !
Thanks !
I'd like to revisit this topic. I think things went in a different direction in #1219 and I would like to come back to the original request. That was to be able to essentially 'stage' everything and save it in the tar file, but do not actually create the Docker image. There would be no interaction with the Docker daemon. This would allow running inside something like a GitLab CI/CD pipeline where there is no access to a Docker daemon. After creating the tar file artifact, a subsequent pipeline stage could use that artifact and Kaniko to create and push an image without needing a Docker daemon.
I think the best proposal was the following command line:
mvn docker:build -Ddocker.saveBuildArchive=target/docker-build.tar -Ddocker.skip.build.image
If no one else is working on this now then I can take a shot at it. I haven't worked on d-m-p before, but I think I have an idea where to start. I can try to put together a straw-man PR to see how close I can get to something usable.
@marcsaegesser : awesome, Thanks a lot. If you are unable to find time for this; I can pick this up.
@rohanKanojia -- I will gladly defer to you for this if you have the time. I hadn't seen this code-base before yesterday so I'm probably not the best person to work on. I have some builds that I need to move into a GitLab CI/CD pipeline using Kaniko and came across this issue that hadn't moved in a while. I figured if I could help I'd give it a shot.
What I've been able to discover so far is that the important stuff happens in BuildService.buildImage(). That does two things. It first builds an archive (the tar file) and then uses that archive and Docker to create the image. It's that second step that we want to skip when docker.skip.build.image is defined.
My instinct says that buildImage() should be two methods: buildArchive() and buildImage() and then BuildMojo.buildAndTag() looks at the docker.skip.build.image property to decide whether or not to call buildImage(). This is similar to how docker.skip.tag is handled now.
Let me know your thoughts on this and how you'd like to proceed.
@marcsaegesser : This flow looks good to me :+1: . Let me try to work on this tomorrow.
Most helpful comment
@marcsaegesser : This flow looks good to me :+1: . Let me try to work on this tomorrow.