文章

Docker镜像构建中使用cache机制对依赖进行复用

在docker中进行构建,然后打包运行,得益于其分阶段构建的特性,能够在控制镜像大小的情况下很好的保持环境一致性的特性。但是docker的机制也使得每次有代码变动之后都必须重新下载依赖,而无法使用maven仓库的本地缓存,导致每次构建都需要很长时间,例如下面的20分钟:

image-20250213212127329

其实这个问题很好解决,借助docker的cache机制,如果没有变动的层会直接使用缓存,因此我们可以将pom.xml文件先复制进容器,然后再进行安装依赖,最后再进行编译, 这样就可以使用上安装依赖的这一层的缓存,而不是在编译的时候自动下载依赖。常规的项目中的Dockerfile这样写:

1
2
COPY pom.xml /app/pom.xml
RUN mvn dependency:go-offline

你真的以为这样就结束了?太天真了!

这只针对简单的项目,对于微服务的项目,有很多的pom文件,并且依赖于子模块,无法使用上述命令进行下载依赖,就会出现子模块去仓库下载不到的现象:

813881d7d1aa7874c8b4775c530cb02

这个只好为每个子模块的pom文件都配置镜像仓库,暂时没有发现更好的办法,从宿主机复制.m2本地仓库也无法使用,可能是文件有变动判断缓存失效了而不使用吧。如果大家对微服务有什么好的办法可以分享一下。

折腾了两个晚上,累死了,睡觉!

2025年2月16更新

发现编译的慢主要是因为网络问题,依赖是从官方下载的,在maven中配置全局镜像就不会那么慢了。在代码仓库中添加settings.xml文件,填入下面的内容:

1
2
3
4
5
6
7
8
9
10
11
12
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
  <mirrors>
    <mirror>
        <id>nexus-aliyun</id>
        <mirrorOf>central</mirrorOf>
        <name>Nexus aliyun</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public</url>
    </mirror>
  </mirrors>
</settings>

然后在Dockerfile中添加复制操作:

1
2
COPY settings.xml /usr/share/maven/conf/settings.xml
RUN mvn clean package -Dmaven.test.skip=true

测试一下:

image-20250216222358587

速度快很多了:

image-20250216222510826

本文由作者按照 CC BY 4.0 进行授权