Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to build dockerFile without pushing it to docker server (DockerInDocker) #1197

Closed
Beennnn opened this issue Apr 9, 2019 · 15 comments · Fixed by #1297
Closed

Unable to build dockerFile without pushing it to docker server (DockerInDocker) #1197

Beennnn opened this issue Apr 9, 2019 · 15 comments · Fixed by #1297
Assignees

Comments

@Beennnn
Copy link

Beennnn commented Apr 9, 2019

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.

@rohanKanojia
Copy link
Member

@Beennnn : Sounds interesting, Could you please create a PR to move this discussion forward?

@rhuss
Copy link
Collaborator

rhuss commented Apr 9, 2019

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 ?

@Beennnn
Copy link
Author

Beennnn commented Apr 10, 2019

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 ?

@rhuss
Copy link
Collaborator

rhuss commented Apr 11, 2019

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.

@Beennnn
Copy link
Author

Beennnn commented Apr 13, 2019

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 ?

@radamanth
Copy link

@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!

@Beennnn
Copy link
Author

Beennnn commented Apr 18, 2019

@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.

@rhuss
Copy link
Collaborator

rhuss commented Apr 21, 2019

@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 ?

@Beennnn
Copy link
Author

Beennnn commented Apr 21, 2019

Thanks @rhuss.
Adding a new goal will be more readable by a user of the docker plugin, but I’m not sure it would me more usable.

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.
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.

@rhuss
Copy link
Collaborator

rhuss commented Apr 22, 2019

Adding a new goal will be more readable by a user of the docker plugin, but I’m 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.

@Beennnn
Copy link
Author

Beennnn commented Apr 22, 2019

Yes 👍Let's do it this way !
Thanks !

@marcsaegesser
Copy link

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.

@rohanKanojia
Copy link
Member

@marcsaegesser : awesome, Thanks a lot. If you are unable to find time for this; I can pick this up.

@marcsaegesser
Copy link

@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.

@rohanKanojia
Copy link
Member

@marcsaegesser : This flow looks good to me 👍 . Let me try to work on this tomorrow.

@rohanKanojia rohanKanojia self-assigned this Nov 12, 2019
rohanKanojia added a commit to rohanKanojia/docker-maven-plugin that referenced this issue Nov 21, 2019
rohanKanojia added a commit to rohanKanojia/docker-maven-plugin that referenced this issue Nov 21, 2019
rohanKanojia added a commit to rohanKanojia/docker-maven-plugin that referenced this issue Nov 21, 2019
rohanKanojia added a commit to rohanKanojia/docker-maven-plugin that referenced this issue Nov 21, 2019
rohanKanojia added a commit to rohanKanojia/docker-maven-plugin that referenced this issue Dec 20, 2019
rohanKanojia added a commit to rohanKanojia/docker-maven-plugin that referenced this issue Jan 8, 2020
rhuss pushed a commit that referenced this issue Jan 8, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants