10

我想在Docker Multi Stage Build的构建阶段的一层中缓存 Maven 依赖项。

我的 Dockerfile 如下所示:

FROM maven:3-jdk-8 as mvnbuild
RUN mkdir -p /opt/workspace
WORKDIR /opt/workspace
COPY pom.xml .
RUN mvn -B -s /usr/share/maven/ref/settings-docker.xml dependency:resolve
COPY . .
RUN mvn -B -s /usr/share/maven/ref/settings-docker.xml package

FROM openjdk:8-jre-alpine
...

```

我基于Docker Multi Stage Build 博客文章也可在 Github 上获得)中提供的示例构建了这个 Dockerfile 。

当我运行构建时,我看到的是两个步骤都下载的依赖项,而不是看到下载一次dependency:resolve然后重新使用的依赖项。package

有没有人有这个工作?我在这里做错了什么?

4

2 回答 2

10

我遇到了同样的问题。我发现这是由于 Maven 目标之间的差异(例如dependency:resolvevs dependency:resolve-plugin)。基本上,dependency:resolve适用于应用程序库,dependency:resolve-plugin适用于插件库。因此,库会在两个 RUN 步骤中下载。

dependency:resolve 告诉 Maven 解析所有依赖项并显示版本。JAVA 9 注意:使用 Java 9 运行时将显示模块名称。

dependency:resolve-plugins 告诉 Maven 解析插件及其依赖项。

https://maven.apache.org/plugins/maven-dependency-plugin/index.html

即使使用dependency:resolve-plugins,Maven 也不会像package内置目标一样下载所有必需的库,并且需要dependency:resolve-plugin在第一次运行时不知道要解析的其他库。我也试过dependency:go-offline没有成功。

一种解决方案是在将代码添加到构建映像之前和之后运行构建目标。这会将所有插件依赖项拉到较低层,从而允许它们被重用。

将此解决方案应用于上面的示例如下:

FROM maven:3-jdk-8 as mvnbuild
RUN mkdir -p /opt/workspace
WORKDIR /opt/workspace
COPY pom.xml .
RUN mvn -B -s /usr/share/maven/ref/settings-docker.xml dependency:resolve-plugins dependency:resolve clean package
COPY . .
RUN mvn -B -s /usr/share/maven/ref/settings-docker.xml clean package

FROM openjdk:8-jre-alpine
于 2017-12-25T15:43:17.177 回答
7

我想在这个上提供我的两分钱。

我从这个 Dockerfile 开始:

FROM maven:3-jdk-10 AS build

RUN mkdir /src
WORKDIR /src
COPY pom.xml .
RUN mvn -B dependency:resolve-plugins dependency:resolve

COPY . .
RUN mvn package

目标是在构建步骤(即mvn package)期间不下载任何依赖项。

我试图添加clean package@Apolozeus 在答案中提到的技巧,但这没有效果。在我的情况下,我在测试期间下载了surefire,并在编译期间下载了一个mapstruct插件。

我最终所做的是在我的文件中明确添加这两个插件,pom.xml以便尽早下载它们:

    <dependency>
        <groupId>org.apache.maven.surefire</groupId>
        <artifactId>surefire-junit4</artifactId>
        <version>2.21.0</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <version>1.2.0.Final</version>
        <scope>compile</scope>
    </dependency>

这是可行的,并且在构建步骤期间不会发生进一步的下载,从而加快了构建速度。

于 2018-04-02T05:59:20.237 回答