【问题标题】:Docker multi-stage build and mounting/sharing from previous stage上一阶段的 Docker 多阶段构建和挂载/共享
【发布时间】:2017-07-19 22:29:52
【问题描述】:

我想使用多阶段构建来避免在每次构建应用程序时下载我的 Java 项目所需的所有 Maven 依赖项。

我正在考虑在第一阶段解决 Maven 依赖项,然后在第二阶段构建应用程序,这将需要访问在前一阶段下载的依赖项。

如果我很好地理解多阶段构建,我可以将在第一阶段创建的文件复制到第二阶段,但理想情况下,我希望能够从依赖项所在的第一阶段“挂载”或“共享”文件夹live而不是复制文件,有可能吗?还是有更好的方法来实现这一目标?

谢谢。

编辑:
这是我考虑的第一个阶段

FROM some-image-with-maven AS maven-repo
WORKDIR /workspace/
COPY pom.xml .
RUN mvn -B -f pom.xml dependency:resolve

但由于 pom 文件在大多数情况下会有所不同(因为我想跨项目共享此阶段),因此解决依赖关系的以下步骤将再次下载所有这些文件(而不是使用缓存层)。

【问题讨论】:

  • 根据我从here 学到的知识,您可以使用关键字AS 命名每个阶段并引用该构建阶段
  • 是的,但我只看到使用阶段名称执行 COPY 的示例

标签: maven docker


【解决方案1】:

如果您不使用卷,则只能从第一阶段复制内容。使用卷时,您可以在基本上是独立容器实例的阶段之间共享数据。 由于缺少清理卷通常无法正确处理,因此我建议保留复制策略。与复制方法相比,使用绑定挂载来共享数据并没有真正的好处。

【讨论】:

  • 您不能在构建时使用卷,它们仅在 17.06 的运行时可用。有讨论添加对挂载目录的支持,但这仍处于讨论/设计阶段。
【解决方案2】:

我认为目前没有办法做到这一点。要从一个构建阶段共享到下一个构建阶段,唯一的选择是将COPY 文件从一个阶段的目录共享到当前阶段。

要将第一阶段用作构建缓存并避免复制所有依赖项,我会在第一阶段运行您的构建。或者,如果您想在各个阶段之间进行额外分离,您可以创建第二个中间阶段 FROM stage1name。然后可以将构建的输出复制到最后一层,避免复制所有构建依赖项。

【讨论】:

  • 我的目标是将第一阶段用作我构建的多个项目的 Maven 存储库(因为如果我没记错,阶段将被缓存)。我的第一阶段目前以RUN mvn -B -f pom.xml dependency:resolve 结束,然后我在下一阶段构建(特别是针对每个项目),但我需要在构建之前复制 1GB 的依赖项,我希望避免这种情况。
  • Dockerfile 的每一行都成为一个缓存层,比整个阶段更细。您可以在第一阶段附加一些额外的构建命令,或者您可以创建一个中间构建阶段 FROM stage1name 来实现您的目标。
  • 当我说“构建”时,我的意思是mvn package ...。假设我构建项目 A 和项目 B 的方式不同,因为我想运行或不运行测试,是否输出东西等等,所以我的 Maven 构建命令不能被重用,这就是为什么它会在项目特定的第二阶段发生,但我所有的 Dockerfile 的第一阶段都是相同的,因此不必在每次 Maven 构建时再次下载依赖项。
  • 缓存发生在比这更低的级别。两个不同的 Dockerfile 用于不同的应用程序,创建不同的镜像,但前几行相同,在构建时将重用另一个镜像的构建缓存的层。 Docker 查看前一层和您正在运行的命令,如果它们匹配,它会跳过使用缓存中的结果层。如果仍有疑问,请使用 MCVE 更新您的问题。
  • 实际上我意识到它不能像我想象的那样工作:我在复制pom.xml后解决了依赖关系,所以由于pom文件大部分时间都不一样,所以所有依赖关系都被下载了在每次 Docker 映像构建时再次...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
  • 2020-07-13
  • 2022-11-25
  • 1970-01-01
  • 2019-09-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多