在之前的博客中,我们介绍了如何使用 gitea actions 做 CI 构建,以及使用 podman 构建多架构镜像。

上面这套系统运行了一段时间之后,我发现了一个问题:构建机器的磁盘占用上升飞快,平均一个镜像构建就要占用 500M 的储存。因为磁盘空间的问题导致我的构建机器上跑的 pod 被驱逐了好几次。

这不太对,对于 docker 镜像来说,它是分层的。如果一个层没有变动,那么就不会重复构建,也不会占用空间。同时,我发现它的构建也变得很慢,要差不多5分钟才能构建出一个镜像。

之前以为可能是 gitea action runner 的问题,但是之后发现可能并不是。让 Deepseek V4 排查了下,发现是镜像中间产物太大+缓存key 失效的问题。

缓存 Key 失效的解决方案是,将 .git 目录添加到 .dockerignore 中:

.git
// ...

但是,.dockerignore 如果设置了,它就不会自动继承 .gitignore 了,所以如果中间有什么中间产物的话,可以一并添加到 .dockerignore 中。

镜像中间产物太大的问题就需要调整下镜像文件的写法,将 go-build cache 手动挂载到 cache 中:

RUN --mount=type=cache,target=/root/.cache/go-build \
    go build ./cmd/server

mount 指令是将某个指定目录挂载到宿主机上的指令,而 type=cache 则是指定目录为缓存目录。这样,构建的时候这个目录里面的内容会被挂在到宿主机上。这样不仅能减少中间层的大小(因为根本不在镜像中了),两次构建之间还能重用缓存降低构建时间。

在使用了上面的优化手段之后,构建时长从 5 分钟降低到了 3 分钟;同时,重复构建后可以正常使用缓存,不会每次都新增几百兆的磁盘占用了。

分类: 未分类

0 条评论

发表回复

Avatar placeholder

您的邮箱地址不会被公开。 必填项已用 * 标注