spotify/dockerfile-maven

Artifact not copied when using Maven `${project.build.directory}` property

jjjjjjje opened this issue · 7 comments

Hi,

I am really confused by the following issue. I need your help :).

I have a parent pom, which is used for all my war projects. In this parent pom, I have:

<plugin>
    <groupId>com.spotify</groupId>
    <artifactId>dockerfile-maven-plugin</artifactId>
    <version>1.3.6</version>
    <executions>
        <execution>
            <goals>
                <goal>build</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <repository>${project.groupId}/${project.artifactId}</repository>
        <tag>${project.version}</tag>
        <buildArgs>
            <ARTIFACT>target/${project.build.finalName}.${project.packaging}</ARTIFACT>
        </buildArgs>
    </configuration>
</plugin>

Now, in the child poms, which are war projects, I can do:

<plugin>
    <groupId>com.spotify</groupId>
    <artifactId>dockerfile-maven-plugin</artifactId>
</plugin>

This works really great. As an example, a Dockerfile looks like this:

FROM tomcat

ARG ARTIFACT
ADD ${ARTIFACT} /usr/local/tomcat/webapps/my-project.war

Now to my bug. In the parent pom, if I replace

    <buildArgs>
        <ARTIFACT>target/${project.build.finalName}.${project.packaging}</ARTIFACT>
    </buildArgs>

by

    <buildArgs>
        <ARTIFACT>${project.build.directory}/${project.build.finalName}.${project.packaging}</ARTIFACT>
    </buildArgs>

this is no longer working. I get the following exception:

[ERROR] ADD failed: stat /var/lib/docker/tmp/docker-builder028011685/home/jjjjeee/projects/my-project/target/my-project-1.0.0-SNAPSHOT.war: no such file or directory

However, that file exists. That would also have been the file if I just did target/${project.build.finalName}.${project.packaging} instead of the not working ${project.build.directory}/${project.build.finalName}.${project.packaging}.

Any ideas? This is really confusing me.

Thanks a lot!

I’d suggest taking a look at the output of mvn help:effective-pom. Possibly the /home/jjjjeee path is not inside the docker context which is sent to the docker daemon (do you expect that to look like an absolute path?).

Good idea, I will do this.

@mattnworb It makes sense now!

With:

    <buildArgs>
        <ARTIFACT>target/${project.build.finalName}.${project.packaging}</ARTIFACT>
    </buildArgs>

It holds the value: target/my-project-1.0.0-SNAPSHOT.war

With:

    <buildArgs>
        <ARTIFACT>${project.build.directory}/${project.build.finalName}.${project.packaging}</ARTIFACT>
    </buildArgs>

It holds the value: /home/.../target/my-project-1.0.0-SNAPSHOT.war

And that is indeed in the docker context, as you thought.

Is there a way to configure this context when using dockerfile-maven-plugin?

You can set <contextDirectory> in the <configuration>:

/**
* Directory containing the Dockerfile to build.
*/
@Parameter(defaultValue = "${project.basedir}",
property = "dockerfile.contextDirectory",
required = true)
private File contextDirectory;

@mattnworb Isn't this some kind of bug then? The basedir is set to ${project.basedir}, so it is /home/jjjjeee/projects/my-project in my case. I am providing a file with path /home/jjjjeee/projects/my-project/target/my-project-1.0.0-SNAPSHOT.war, which is an absolute path certainly below the basedir.

Shouldn't we be smart enough to translate this absolute path in to the relative path target/my-project-1.0.0-SNAPSHOT.war?

I wouldn't classify this as a bug in dockerfile-maven, as it is docker itself that requires that the paths in the Dockerfile be relative paths to the context. See moby/moby#4592 as a reference. Absolute paths in the Dockerfile would make your build a lot less portable, for instance.

For example:

$ pwd
/tmp/foobar

$ ls
Dockerfile	hello.txt

$ cat Dockerfile
FROM ubuntu
RUN echo hello
ADD /tmp/foobar/hello.txt hello.txt

$ docker build .
Sending build context to Docker daemon   2.56kB
Step 1/3 : FROM ubuntu
 ---> 20c44cd7596f
Step 2/3 : RUN echo hello
 ---> Using cache
 ---> e37466936e64
Step 3/3 : ADD /tmp/foobar/hello.txt hello.txt
ADD failed: stat /var/lib/docker/tmp/docker-builder205366892/tmp/foobar/hello.txt: no such file or directory

I would agree that the fact that the Maven property ${project.build.directory} is an absolute path can be confusing, but that is Maven for you 🤷‍♂️