Running on local machine, no problem, I can run the copy (cp) command to transfer file to volume, and after build ends file is present.
Running on Jenkins on docker, no errors on build, but no file is present, in fact volume directory is not created too.
Dockerfile (Only parts about cp and volume):
ENTRYPOINT cp -rf installer.msi /data
VOLUME /data
Plugin configuration:
<images>
<image>
<name>neocode/neocode-wix</name>
<alias>neocode-wix</alias>
<build>
<dockerFileDir>${project.basedir}/target/docker-image</dockerFileDir>
</build>
<run>
<namingStrategy>alias</namingStrategy>
<volumes>
<bind>
<volume>${project.basedir}/target/msi-installer:/data</volume>
</bind>
</volumes>
</run>
</image>
</images>
mvn -v) : 3.5.0Not sure what you are trying to achieve. The configuration given is only relevant for running a docker container, not for creating the image. Could you please your use case a bit in more detail and possibly give a full example so that we can reproduce the issue ?
Hi @rhuss,
Before ENTRYPOINT I just call some executable on my container to generate a Windows MSI.
The point here is that if I run my build in local machine, no problem, file (installer.msi) is present in mapped volume (target/msi-installer:/data).
But, when I run the same build in my Jenkins, the folder is always empty, without errors on build.
The big diference is that my Jenkins runs on a docker container, and I installed docker in this container to have a "docker-on-docker" (basically mapping docker.sock):
-v /var/run/docker.sock:/var/run/docker.sock
I couldn't resolve this problem, so I adjusted my maven build to run "docker -cp" directly before stop container, and it works!
EDIT: In local machine and in my special jenkins
Sorry, still don't get it. Everything what you configure in <run> is only evaluated for mvn docker:start. For mvn docker:build only the parts in <build> is relevant. So, I don't understand how the volume mapping ever should affect the build of the docker image with mvn docker:build.
Just a confusion with word "build", I always was talking about maven build process, no docker:build goal.
The problem occurs on docker:start (where my entrypoint executes a copy command to /data).
Problem summary: No file appears to be copied to host directory (only when executed inside a docker container).
This is because with DOOD-style (docker-on-outer docker) docker-on-docker (-v /var/run/docker.sock:/var/run/docker.sock), the docker command-line client inside the DOOD container uses the host machine's docker daemon, _and all bind-mount filesystem paths are looked up on the host machine_.
As a result, with DOOD-style docker-on-docker, you cannot bind-mount anything into a container started by a DOOD container that does not exist on the _host_ filesystem.
You need to run Jenkins with full DIND-style docker-on-docker (jpetazzo/dind) if you need to run containers with bind-mounts from inside other containers.
This is a limitation of the Docker software and there is no way for the docker-maven-plugin to work around it.
You _can_ - depending on your use-case - bind-mount some paths from your host machine into your Jenkins at _exactly the same place_ (e.g. -v /tmp/some-dir:/tmp/some-dir), and then any containers started by Jenkins with bind-mounts from those paths, will succeed - but this is manual, doesn't scale, and can't be used in all cases.
@Gengar003 Tks for deep explanation about the "problem" :) and tip about tmp hack.
Using "docker -cp" command solves my problem, so I will not use dind for while.
I'm closing issue, but would be nice if it will be tagged someway or the information included on wiki/readme.
@dyorgio I am facing the same issue. Can you please share your workaround "docker -cp" with an example?
Hi @RaviH ! Yes, I Will try to sumarize here.
Using maven-antrun-plugin
.xml
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>copy file from container</id>
<phase>package</phase> <!-- I use package phase, adapt to your use -->
<configuration>
<target>
<taskdef resource="net/sf/antcontrib/antcontrib.properties" classpathref="maven.plugin.classpath" />
<if>
<os family="mac"/>
<then>
<exec executable="/usr/local/bin/docker" osfamily="mac" failonerror="true">
<arg value="cp"/>
<arg value="YOUR-CONTAINER-NAME:/PATH/TO/FILE/INSIDE/CONTAINER"/>
<arg value="${basedir}/target"/>
</exec>
</then>
<else>
<if>
<os family="unix"/>
<then>
<exec executable="/usr/bin/docker" osfamily="unix" failonerror="true">
<arg value="cp"/>
<arg value="YOUR-CONTAINER-NAME:/PATH/TO/FILE/INSIDE/CONTAINER"/>
<arg value="${basedir}/target"/>
</exec>
</then>
</if>
</else>
</if>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>ant-contrib</groupId>
<artifactId>ant-contrib</artifactId>
<version>20020829</version>
</dependency>
</dependencies>
</plugin>
Hi @dyorgio,
Thank you so much. How do you get the container name?
Hello again,
This plugin supports container name set:
.xml
<image>
<alias>YOUR-CONTAINER-NAME</alias>
<run>
<namingStrategy>alias</namingStrategy>
</run>
</image>
Most helpful comment
This is because with DOOD-style (docker-on-outer docker) docker-on-docker (
-v /var/run/docker.sock:/var/run/docker.sock), the docker command-line client inside the DOOD container uses the host machine's docker daemon, _and all bind-mount filesystem paths are looked up on the host machine_.As a result, with DOOD-style docker-on-docker, you cannot bind-mount anything into a container started by a DOOD container that does not exist on the _host_ filesystem.
You need to run Jenkins with full DIND-style docker-on-docker (jpetazzo/dind) if you need to run containers with bind-mounts from inside other containers.
This is a limitation of the Docker software and there is no way for the
docker-maven-pluginto work around it.You _can_ - depending on your use-case - bind-mount some paths from your host machine into your Jenkins at _exactly the same place_ (e.g.
-v /tmp/some-dir:/tmp/some-dir), and then any containers started by Jenkins with bind-mounts from those paths, will succeed - but this is manual, doesn't scale, and can't be used in all cases.