I have the following multi-stage dockerfile
that attempts to copy each module of my multi-module java maven
project and build my ear
file using mvn clean install
.
dockerfile:
# Copy files from local to maven image and build ear
FROM maven:3.5-jdk-8 AS build
COPY module1 /usr/src/app/src
COPY module2 /usr/src/app/src
COPY module3 /usr/src/app/src
COPY pom.xml /usr/src/app
RUN mvn -f /usr/src/app/pom.xml clean install
# Create server image + rest of docker file (working ok)
The error that I am getting is as follows:
Step 8/20 : RUN mvn -f /usr/src/app/pom.xml clean install
---> Running in cf9d8c1ef9ed
[INFO] Scanning for projects...
[ERROR] [ERROR] Some problems were encountered while processing the POMs:
[FATAL] Non-resolvable parent POM for com.company.web:api:21.01-SNAPSHOT:
Could not find artifact com.company.parent:jee6:pom:1.0.1-SNAPSHOT and
'parent.relativePath' points at wrong local POM @ line 8, column 10
@
[ERROR] The build could not read 1 project -> [Help 1]
The section in the pom.xml
that corresponds to this error:
<parent>
<groupId>com.company.parent</groupId>
<artifactId>jee6</artifactId>
<version>1.0.1-SNAPSHOT</version>
</parent>
I assume this issue because when trying to run the command in the maven docker image it cannot see my local .m2
folder? And the dependency that it is looking for is a private dependency on my local machine.
Would also copying my maven settings.xml
help?
How can I resolve this? I do not want someone to have to have Maven installed on their machine in order to run this dockerfile.
Maven throws “Missing artifact error” when a dependency is not recognized or a dependency artifact cannot be found either in the local repository or the remote repository depending on how we have configured our project to get the dependencies (check the <url> tag in pom.xml which helps to determine where maven will refer the dependencies).
Each maven project can have exactly one artifact like a jar, war, ear, etc. Each artifact has a group ID (usually a reversed domain name, like com.jcg.maven), an artifact ID (just a name), and a version string.
Now, the submodules are regular Maven projects, and they can be built separately or through the aggregator POM. By building the project through the aggregator POM, each project that has packaging type different than pom will result in a built archive file.
Maven's Multi-Module Project A multi-module project is built from an aggregator POM that manages a group of submodules. In most cases, the aggregator is located in the project's root directory and must have packaging of type pom.
Dependency com.company.parent:jee6:pom:1.0.1-SNAPSHOT
seems to be private, your Maven command inside Docker build needs to be able to either download it from private repository or have it readily accessible.
I assume this issue because when trying to run the command in the maven docker image it cannot see my local .m2 folder?
Yes, it then cannot see your settings.xml
with private repository config, or local dependency if it's already available locally.
Would also copying my maven settings.xml help?
It's better not to: your settings.xml
(and eventual secrets within) may be available to anyone using your image later. Using a secret mount with BuildKit would be a better solution (see below)
You have multiple solutions:
settings.xml
as secret during buildThis solution assumes you have a settings.xml
configured with proper credentials to access private registry.
Use Docker BuildKit with --mount=secret
to load settings.xml
as secret with a Dockerfile
such as:
# syntax=docker/dockerfile:1.2
# Required comment at top of Dockerfile for using BuildKit
FROM maven:3.5-jdk-8 AS build
COPY module1 /usr/src/app/src
COPY module2 /usr/src/app/src
COPY module3 /usr/src/app/src
COPY pom.xml /usr/src/app
# Use your secret settings.xml
RUN --mount=type=secret,id=mvnsettings,target=/root/.m2/settings.xml \
mvn -f /usr/src/app/pom.xml clean install
And build command such as:
DOCKER_BUILDKIT=1 docker build --secret id=mvnsettings,src=$HOME/.m2/settings.xml .
Maven should then be able to download parent dependency during build.
Note: this is NOT COPY
ing the settings.xml
in image, as the secret settings.xml
will only be made available for the specified build step and won't be persisted in final image.
com.company.parent:jee6
pom.xml
during buildThis solution is less practical and may not solve problem entirely:
com.company.parent:jee6:pom:1.0.1-SNAPSHOT
pom.xml
file available in build contextpom.xml
may refer to other private dependencies. You would have to include them the same way.... But it still may be worth a try.
You can do something like:
FROM maven:3.5-jdk-8 AS build
# Copy and install parent pom
COPY parent-pom.xml /tmp/parent/pom.xml
RUN mvn -f /tmp/parent/pom.xml clean install
COPY module1 /usr/src/app/src
COPY module2 /usr/src/app/src
COPY module3 /usr/src/app/src
COPY pom.xml /usr/src/app
RUN mvn -f /usr/src/app/pom.xml clean install
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With