多模块 Maven 项目和 Docker:找不到工件?

jav*_*900 6 java dependencies pom.xml maven docker

我有以下多阶段dockerfile尝试复制我的多模块java maven项目的每个模块并ear使用mvn clean install.

码头档案:

# 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)
Run Code Online (Sandbox Code Playgroud)

我得到的错误如下:

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]
Run Code Online (Sandbox Code Playgroud)

pom.xml中与此错误对应的部分:

<parent>
<groupId>com.company.parent</groupId>
<artifactId>jee6</artifactId>
<version>1.0.1-SNAPSHOT</version>
</parent>
Run Code Online (Sandbox Code Playgroud)

我假设这个问题是因为当尝试在 Maven docker 映像中运行命令时,它看不到我的本地.m2文件夹?它正在寻找的依赖项是对我本地机器的私有依赖项。

复制我的 Maven 也会有settings.xml帮助吗?

我该如何解决这个问题?我不希望有人必须在他们的机器上安装 Maven 才能运行这个 dockerfile。

Pie*_* B. 5

依赖关系com.company.parent:jee6:pom:1.0.1-SNAPSHOT似乎是私有的,Docker 构建中的 Maven 命令需要能够从私有存储库下载它或易于访问它。

我假设这个问题是因为当尝试在 Maven docker 映像中运行命令时,它看不到我的本地 .m2 文件夹?

是的,它无法看到您的settings.xml私有存储库配置,或者本地依赖项(如果它已在本地可用)。

复制我的 Maven settings.xml 也会有帮助吗?

最好不要这样做:您的settings.xml(以及其中最终的秘密)可能会被以后使用您的图像的任何人看到。使用 BuildKit 的秘密安装将是一个更好的解决方案(见下文)


您有多种解决方案:

settings.xml在构建期间作为秘密安装

此解决方案假设您已settings.xml 配置了正确的凭据来访问私有注册表

使用Docker BuildKit来作为秘密--mount=secret加载,例如:settings.xmlDockerfile

# 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
Run Code Online (Sandbox Code Playgroud)

并构建命令,例如:

DOCKER_BUILDKIT=1 docker build --secret id=mvnsettings,src=$HOME/.m2/settings.xml . 
Run Code Online (Sandbox Code Playgroud)

然后,Maven 应该能够在构建期间下载父依赖项。

注意:这不是COPYsettings.xml图像中,因为秘密settings.xml仅可用于指定的构建步骤,并且不会保留在最终图像中。

com.company.parent:jee6 pom.xml构建期间复制

这种解决方案实用性较差,可能无法完全解决问题:

  • 需要com.company.parent:jee6:pom:1.0.1-SNAPSHOT pom.xml在构建上下文中提供可用的文件
  • 您的父级pom.xml可能会引用其他私有依赖项。您必须以相同的方式包含它们。

...但它仍然值得一试。

你可以这样做:

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
Run Code Online (Sandbox Code Playgroud)