我管理着一个大型专有系统,该系统被Java中的大约十二个服务所损害。我们有一组核心的Java库,它们都共享),并且所有组件/应用程序都是使用maven构建的。尽管每个应用程序都有自己独特的一组依赖关系,但在核心SDK罐之外。我不知道在docker内部构建和部署的最佳方法是什么。理想情况下,我希望使用多阶段构建方法在docker中获得整个生命周期。但是,我看不到如何使用大量的依赖项来优化它。
看来我可以做两种方法。
使用maven和CI服务器上的公共缓存(jenkins)像以前一样进行构建,以便依赖项一次被提取并缓存,并且所有应用程序都可以访问。然后为每个应用程序创建一个dockerfile,该文件仅将产品jar及其依赖项(或胖子jar)复制到容器中,并将其设置为执行。这种方法的缺点是,构建本身在开发人员和CI服务器之间可能有所不同。可能会使用诸如nexus之类的本地Maven缓存,只是为了避免每次都从互联网上拉出部门?但这仍然不能解决开发版本不一定与CI构建环境匹配的问题。
为每个项目使用多阶段dockerfile。我已经尝试过了,它确实起作用了,我设法将maven依赖项层缓存起来,这样就不会太频繁地获取它。不幸的是,每个应用程序的中间构建层达到1-2gb,并且我无法从守护程序中删除“悬空的”中间件,否则所有缓存都将消失。这也意味着,如果pom中发生某些更改,则必须为每个应用程序下载大量的jar文件。 (即它们都使用junit和log4j以及许多其他相似之处)
有没有一种解决我看不到的最佳方法?我发现的所有博客基本上都专注于上述两种方法(有些专注于在容器中运行Maven本身,这对我来说真的解决不了任何问题)。如果没有其他好的解决方案,我可能最终需要选择选项1。
我检查了stackoverflow和博客,我发现的所有内容似乎都假设您实际上只是在构建一个应用程序而不是其中的一套,在这里重要的是不要重复依赖项下载。< / p>
答案 0 :(得分:1)
我认为只要在Maven构建中设置--update-snapshots
选项,就可以使用.m2 / repository文件系统缓存。它可以更好地扩展,因为您在每个构建环境中仅对每个.jar缓存一次,而不对每个应用程序缓存一次。此外,对单个依赖项的更改不会使整个缓存失效,如果使用docker-layer-caching就是这种情况。
不幸的是,目前无法与多阶段构建很好地结合使用,但是您并不是唯一要求它的人。
This issue请求向docker build命令添加一个--volume
选项。 This one要求在Dockerfile:RUN --mount=m2repo=/var/mvn/repo mvn install
中允许这样的指令。
这两个功能都可以让您在多阶段构建过程中使用本地maven文件系统缓存。
目前,我建议您将选项1保留为解决方案,除非您面临由于不同的构建环境而导致的许多问题。