fabric8io / docker-maven-plugin

Maven plugin for running and creating Docker images
https://dmp.fabric8.io
Apache License 2.0
1.88k stars 642 forks source link

Unable to locate the project artifact during docker:build #389

Open vrenjith opened 8 years ago

vrenjith commented 8 years ago

I am unable to really figure out which relative path is used by docker during the build process. Hence this request. The docker:build always fails with the output

[INFO] --- docker-maven-plugin:0.13.9:build (default-cli) @ sample-spring-boot-docker ---
[INFO] Copying files to /home/vagrant/SampleApp/greeting-service/target/docker/greeting-service/build/maven
[INFO] Building tar: /home/vagrant/SampleApp/greeting-service/target/docker/greeting-service/tmp/docker-build.tar
[ERROR] DOCKER> Error building image: lstat build/maven/sample-spring-boot-docker-0.1.0.jar: no such file or directory
[ERROR] DOCKER> lstat build/maven/sample-spring-boot-docker-0.1.0.jar: no such file or directory
[ERROR] DOCKER> lstat build/maven/sample-spring-boot-docker-0.1.0.jar: no such file or directory
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE

The pom.xml, Dockerfile and find output is given below:

<plugin>
                <groupId>org.jolokia</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>0.13.9</version>
                <configuration>
                    <images>
                        <image>
                        <name>greeting-service</name>
                        <build>
                            <assembly>
                                <descriptorRef>artifact</descriptorRef>
                                <dockerFileDir>.</dockerFileDir>
                            </assembly>
                        </build>
                        </image>
                    </images>
                </configuration>
            </plugin>
FROM somebaseimage

ADD sample-spring-boot-docker-0.1.0.jar app.jar
....
vagrant@greeting-service-host:~/SampleApp/greeting-service/target/docker$ find .
.
./greeting-service
./greeting-service/build
./greeting-service/build/maven
./greeting-service/build/maven/sample-spring-boot-docker-0.1.0.jar
./greeting-service/tmp
./greeting-service/tmp/docker-build.tar
./greeting-service/work
rhuss commented 8 years ago

You have to distinguish between two build modes:

Both are currently more or less orthogonal (however there is work to let a Dockerfile reference the assembly defined in the pom).

In your example you are using more or less both which at least seems to copy the assembly in the build directory. When you then use dockerFileDir then the build dir is the context dir for the Docker build. So you should use ADD maven/sample-spring-boot-docker-0.1.0.jar app.jar in the Dockerfile.

However, this approach is not recommended, since you would need to update the version number all the time. Instead you should use an assembly which maps the artifact name to a fixed outputFileName (this can be done in a custom assembly descriptor). Also, you could use a basedir / in the plugin's build>assembly configuration so that it will be automatically added and you wouldn't need to specify a dockerfile dir.

Do you have the full example as a github project ? If so, I could send you a PR with my suggestions.

vrenjith commented 8 years ago

Thanks Roland for the update.

<configuration>
                    <images>
                        <image>
                        <name>greeting-service</name>
                        <build>
                            <assembly>
                                <dockerFileDir>.</dockerFileDir>
                            </assembly>
                            <assembly>
                                <descriptorRef>artifact</descriptorRef>
                                <outputFileName>app.jar<outputFileName>
                            </assembly>                        
                           </build>
                        </image>
                    </images>
                </configuration>
                        <build>
                            <assembly>
                                <basedir>/</basedir>
                                <descriptorRef>artifact</descriptorRef>
                                <dockerFileDir>.</dockerFileDir>
                            </assembly>
                        </build>
vrenjith commented 8 years ago

Roland, I still dont get how I can reference files that are in different directories to be included while building the image using a Dockerfile. Currently I am giving relative path from the build which doesn't look that nice for me. In fact it gives the below error: DOCKER> Error building image: Forbidden path outside the build context: ../../src/main/resources/config/application.yml Is there any way to include additional files that will get copied into the build directory so that when the docker build runs it can find all of them?

rhuss commented 8 years ago

If you want to reference artifact / dependencies and files from different directory I really recommend to use only an own assembly (not a predefined as described with artifactRef but of course this could be also used as a blueprint

Within the assembly you can define so called filesets which refers to plain files. This all is documented in the documentation to the assembly plugin (and also, please read the plugins documentation which explains how to include the assembly).

With the dockerfile mode this is not easy possible. You could do the copying on your own with e.g. the resource plugin, but that's quite involved.

vrenjith commented 8 years ago

Thanks Roland. I managed to currently build it with a mix of stuff. I have another question regarding the phases. In my Jenkins job I am only calling mvn clean install test and I see that a docker start is being attempted. The executions block in the pom.xml looks like the following:

<executions>
    <execution>
        <id>start</id>
        <phase>pre-integration-test</phase>
        <goals>
            <goal>build</goal>
            <goal>start</goal>
        </goals>
    </execution>
    <execution>
        <id>stop</id>
        <phase>post-integration-test</phase>
        <goals>
            <goal>stop</goal>
        </goals>
    </execution>
</executions>

I am not sure why a run is being invoked when I do an mvn test.

nitin-tiwari commented 7 years ago

@vrenjith I'm facing the similar issue, where I'm trying to build and run the image from a different module than the one where Dockerfile is. Apparently you solved the problem of jar not being located can you please share your config to refer to the dependencies from different module?

vrenjith commented 7 years ago

@nitin-tiwari

pom.xml

    <build>
        <plugins>
            <plugin>
                <groupId>io.fabric8</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>0.14.0</version>
                <configuration>
                    <images>
                        <image>
                            <alias>some-service-name-1</alias>
                            <name>${localregistry}/${docker.image.prefix}/some-service-name</name>
                            <build>
                                <assembly>
                                    <descriptorRef>artifact</descriptorRef>
                                    <dockerFileDir>${project.basedir}/.</dockerFileDir>
                                </assembly>
                            </build>
                            <run>
                                <namingStrategy>alias</namingStrategy>
                                                                <envPropertyFile>LocalEnv</envPropertyFile>
                                <net>pod-network</net>
                                <ports>
                                                                        <port>8001:7199</port>
                                    <port>8000:8080</port>
                                </ports>
                            </run>
                        </image>
                    </images>
                </configuration>
                <executions>
                    <execution>
                        <id>start</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>build</goal>
                            <goal>start</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>stop</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>stop</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

Dockerfile

FROM which_ever_base_image
ADD maven/some-service-spring-boot-docker-0.1.0.jar app.jar
CMD java -jar app.jar