如何优化多个相关 maven java 项目的 docker 构建?(缓存)

我管理着一个大型专有系统,该系统在 Java 中受到了大约十几个服务的影响。我们有一组核心的 java 库,它们都共享),并且所有组件/应用程序都是使用 maven 构建的。在核心 SDK jar 之外,尽管每个应用程序都有自己独特的依赖项集。我无法弄清楚在 docker 内部构建和部署的最佳方法是什么。理想情况下,我希望整个生命周期都在 docker 中,使用多阶段构建方法。但是,我看不到如何使用大量依赖项来优化它。

看起来我可以做两种方法。

  1. 像以前一样构建,使用 maven 和 CI 服务器 (jenkins) 上的公共缓存,以便获取依赖项并缓存一次,并且所有应用程序都可以访问。然后为每个应用程序创建一个 dockerfile,将产品 jar 及其依赖项(或胖 jar)复制到容器中,并将其设置为执行。这种方法的缺点是构建本身可能在开发人员和 CI 服务器之间有所不同。可能会使用像 nexus 这样的本地 Maven 缓存来避免每次都从互联网上拉取 deps?但这仍然不能解决开发构建不一定匹配 CI 构建环境的问题。

  2. 为每个项目使用多阶段 dockerfile。我试过这个,它确实有效,我设法让 maven 依赖层缓存,这样它就不会太频繁地获取。不幸的是,每个应用程序的中间构建层达到了 1-2gb,我无法从守护程序中删除“悬空”中间体,否则所有缓存都被吹走了。这也意味着如果 poms 中的某些内容发生变化,则必须为每个应用程序下载 jar 中的大量重复。(即它们都使用 junit 和 log4j 以及许多其他相似之处)

有没有办法以最佳方式解决这个我没有看到的问题?我发现的所有博客基本上都集中在上面的 2 种方法上(有些则专注于在容器中运行 maven 本身,这对我来说真的没有解决任何问题)。如果没有任何其他好的解决方案,我可能最终需要选择选项 1。

我已经查看了 stackoverflow 和博客,我能找到的所有内容似乎都假设您实际上只是在构建一个应用程序而不是其中的一个套件,因此不重复依赖项下载变得很重要。


茅侃侃
浏览 204回答 1
1回答

人到中年有点甜

我认为只要您--update-snapshots在 Maven 构建中设置该选项,就可以使用 .m2/repository 文件系统缓存。它可以更好地扩展,因为您在每个构建环境中只缓存每个 .jar 一次,而不是每个应用程序一次。此外,单个依赖项的更改不会使整个缓存失效,如果您使用 docker-layer-caching,就会出现这种情况。不幸的是,目前这不能与多阶段构建很好地结合,但您并不是唯一需要它的人。 此问题要求向--volumedocker build 命令添加一个选项。这一个请求允许在Dockerfile这样的说明:RUN --mount=m2repo=/var/mvn/repo mvn install。这两个功能都允许您在多阶段构建期间使用本地 Maven 文件系统缓存。目前我建议保留您的选项 1 作为解决方案,除非您面临许多由于不同的构建环境而导致的问题。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java