Docker RUN --mount=type=cache使用疑问:文件消失、缓存清理等
问题解答
1. 为何使用--mount=type=cache时文件会突然消失?
--mount=type=cache的作用是用BuildKit维护的缓存目录替换容器内的目标路径,而非在原有路径上追加内容。你这里挂载了target=${GOPATH}(即/go),意味着执行这条RUN命令时,容器里的/go目录被替换成了缓存目录——这个缓存目录初始为空(或仅保留之前缓存的少量内容,比如你看到的go.mod),自然看不到之前COPY进去的代码文件。
简单来说:缓存挂载会“覆盖”目标路径,原有路径的内容会被隐藏,只能看到缓存目录里的内容。
2. 如何清理这类--mount=type=cache缓存,同时保留其他Docker缓存?
这类缓存属于BuildKit的执行缓存挂载(exec.cachemount),和镜像层缓存、apt缓存相互独立,可单独清理:
- 使用
docker buildx prune命令,通过过滤器精准清除这类缓存:docker buildx prune --filter type=exec.cachemount -f - 如果你给缓存挂载指定了
name参数(比如--mount=type=cache,target=/go/pkg/mod,name=gomod),还能通过名称更精准地清理:docker buildx prune --filter type=exec.cachemount --filter name=gomod -f
该操作只会删除--mount=type=cache创建的缓存,镜像构建步骤缓存、apt缓存等都会保留。
3. 在使用COPY . .的情况下,是否仍能缓存go mod download及所有Go构建缓存?
完全可以,但需要调整缓存挂载的目标路径——不要挂载整个GOPATH,而是挂载Go工具链实际依赖的缓存目录:
Go的模块缓存存在${GOPATH}/pkg/mod,构建缓存默认在${GOPATH}/pkg/mod/cache或GOCACHE环境变量指定的路径(通常为/root/.cache/go-build)。正确的做法是拆分构建步骤,先缓存依赖下载,再复制代码:
FROM debian ENV GOPATH=/go ENV GOCACHE=/go/build-cache WORKDIR ${GOPATH}/src/github.com/my/prj # 先复制依赖文件,单独处理缓存 COPY go.mod go.sum ./ RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target=${GOCACHE} \ go mod download # 再复制全部代码 COPY ./ ./ # 构建时继续挂载构建缓存 RUN --mount=type=cache,target=${GOCACHE} \ go build -o myapp .
这样即使COPY . .因代码变更失效,只要go.mod和go.sum未修改,go mod download的步骤就会复用缓存,构建缓存也能持续生效。
内容的提问来源于stack exchange,提问作者xpt
相关产品推荐
相关产品推荐

