将本地Docker镜像迁移至docker buildx的构建问题咨询
问题:使用docker buildx迁移多阶段本地镜像构建遇到的问题
我此前使用本地构建的多个Docker镜像,现尝试迁移至使用docker buildx进行构建。场景是先通过本地容器构建源码产物,再由生产容器引用该本地构建容器。
目录下有两个Dockerfile:
# Dockerfile.builder FROM maven:3-eclipse-temurin-17 ARG VERSION # clone git repository, do building things
# Dockerfile.prod ARG BUILDER_TAG FROM builder:$BUILDER_TAG as builder # pull in build artifacts from builder container, do other things
原构建命令如下:
docker build --no-cache --build-arg VERSION=$BUILD_VERSION -t builder-container:${BUILD_VERSION} -f Dockerfile.builder . docker build --no-cache --build-arg BUILDER_TAG=$BUILD_VERSION -t prod-container:${BUILD_VERSION} -f Dockerfile.prod .
我尝试适配为docker buildx构建,使用命令:
docker buildx build --no-cache --build-arg VERSION=$BUILD_VERSION -t builder:${BUILD_VERSION} - < Dockerfile.builder
执行后出现报错:
[+] Building 4.3s (2/2) FINISHED => ERROR [internal] load .dockerignore 4.0s => => transferring context: 0.0s => ERROR [internal] load build definition from Dockerfile 4.3s => => transferring dockerfile: 30B 0.0s ------ > [internal] load .dockerignore: ------ ------ > [internal] load build definition from Dockerfile: ------ ERROR: failed to solve: failed to read dockerfile: failed to remove: /var/lib/docker/zfs/graph/hiqgpytehhglat0nn1a06dop1/.zfs: unlinkat /var/lib/docker/zfs/graph/hiqgpytehhglat0nn1a06dop1/.zfs/snapshot: operation not permitted
附buildx配置信息:
docker buildx inspect Name: default Driver: docker Last Activity: 2023-02-15 03:27:29 +0000 UTC Nodes: Name: default Endpoint: default Status: running Buildkit: 23.0.1 Platforms: linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/386
解答
1. 当前buildx调用方式的问题
你用- < Dockerfile.builder通过STDIN传递Dockerfile的方式存在两个问题:
- 这种方式没有指定构建上下文目录(缺少末尾的
.),导致buildx尝试加载当前目录的.dockerignore但上下文为空,触发异常 - 结合ZFS存储驱动的权限限制,出现了无法清理临时目录的报错
这种方式不符合你的场景需求,你的构建需要本地上下文支持(即使当前是clone git,后续若有本地源码复制也需要),且生产镜像需要引用本地构建的builder镜像,必须保证builder镜像正确存入本地Docker仓库。
2. 正确的buildx构建命令
只需将原docker build替换为docker buildx build,保留上下文目录即可:
构建builder镜像
docker buildx build --no-cache --build-arg VERSION=$BUILD_VERSION -t builder-container:${BUILD_VERSION} -f Dockerfile.builder .
构建prod镜像
docker buildx build --no-cache --build-arg BUILDER_TAG=$BUILD_VERSION -t prod-container:${BUILD_VERSION} -f Dockerfile.prod .
3. 是否需要docker buildx create?
不需要。当前你的buildx使用的是docker驱动,这种模式下buildx会将构建的镜像直接存入本地Docker镜像仓库,行为和传统docker build完全一致。只有当你需要跨平台构建、使用独立BuildKit容器(container驱动)等高级场景时,才需要创建新的builder实例。
4. 是否需要清理graph目录?
暂时不需要。报错是由于STDIN构建方式的上下文处理异常导致的,使用正确的上下文目录构建后该问题应该会消失。如果后续仍出现存储驱动相关异常,可以尝试重启Docker服务,或检查ZFS文件系统的权限配置。
5. buildx与传统docker build的核心差异
- buildx基于BuildKit引擎,支持更多特性:跨平台构建、并行依赖解析、更灵活的缓存策略、输出格式自定义等
- 使用
docker驱动时,buildx和传统build行为一致;使用container驱动时,构建的镜像默认不会存入本地仓库,需通过--load参数加载到本地 - buildx支持多节点分布式构建,传统build仅支持单节点
内容的提问来源于stack exchange,提问作者4oo4
相关产品推荐
相关产品推荐

