传统的 docker build 有几个限制:只能为当前机器架构构建镜像,缓存策略简单,不支持多阶段构建优化等高级功能。
Docker Buildx 是 Docker 官方推出的 BuildKit 构建工具,能解决这些问题。它支持多架构镜像构建、高级缓存管理和性能优化。
安装与配置
先检查环境:
# 检查 Docker 版本(需要 19.03+)docker --version
# 检查 buildx 是否可用docker buildx version
# 查看可用的 builderdocker buildx ls对于 Docker 19.03+ 用户,需要启用实验性功能:
export DOCKER_BUILDKIT=1docker buildx create --useBuilder 是 BuildKit 后端的配置,决定构建运行的位置和环境。Buildx 支持四种驱动类型:docker、docker-container、kubernetes、remote。单架构快速构建用 docker 驱动,多架构构建用 docker-container 驱动,CI/CD 大规模构建可以考虑 kubernetes 驱动。
创建支持多平台的 Builder:
# 创建新的 builder 实例(使用 docker-container 驱动)docker buildx create --name multiarch-builder --driver docker-container --use
# 启动并检查 builderdocker buildx inspect --bootstrap
# 查看支持的平台docker buildx inspect --bootstrap | grep Platforms# 输出示例:Platforms: linux/amd64, linux/arm64, linux/arm/v7推送到 Registry 前需要先登录:
# Docker Hub 登录docker login
# 或者指定 registrydocker login ghcr.iodocker login docker.io常用 Builder 管理命令:
# 查看现有 builderdocker buildx ls
# 切换 builderdocker buildx use mybuilder
# 查看 builder 详情docker buildx inspect mybuilder
# 删除 builderdocker buildx rm mybuilder基础构建命令
先准备一个简单的 Dockerfile:
FROM alpine:latestCMD ["echo", "Hello from Docker"]单平台构建(本地测试):
# 基础构建 - 结果加载到本地 docker 镜像docker buildx build -t myapp:latest .
# 带多个标签docker buildx build -t myapp:latest -t myapp:1.0 .-t 参数给镜像打标签,. 表示使用当前目录下的 Dockerfile。
多平台构建(推送到 Registry),zhijunio 为我的 docker 用户名:
docker buildx build \ --platform linux/amd64,linux/arm64 \ --push \ -t docker.io/zhijunio/myapp:latest \ -t docker.io/zhijunio/myapp:1.0 \ .--platform指定目标架构,多个平台用逗号分隔。--push表示构建完成后直接推送到 Registry(需要提前docker login)。
输出选项:
| 选项 | 说明 | 限制 |
|---|---|---|
--load | 加载到本地 docker | 仅限单平台 |
--push | 推送到 Registry | 多平台必须 |
--output | 输出到目录 | 本地调试用 |
| 无 | 仅更新缓存 | 不生成镜像 |
注意 --load 和--push不能同时使用,多平台构建必须用--push。
缓存优化
Buildx 支持多种缓存后端,合理使用可以显著提升 CI/CD 构建速度。
使用 Registry 缓存(需要提前 docker login):
# 导出缓存到 registrydocker buildx build \ --cache-to type=registry,ref=docker.io/zhijunio/cache:myapp \ --push \ -t docker.io/zhijunio/myapp:latest \ .
# 从 registry 导入缓存docker buildx build \ --cache-from type=registry,ref=docker.io/zhijunio/cache:myapp \ --push \ -t docker.io/zhijunio/myapp:latest \ .
# 同时导入导出(推荐)docker buildx build \ --cache-from type=registry,ref=docker.io/zhijunio/cache:myapp \ --cache-to type=registry,ref=docker.io/zhijunio/cache:myapp,mode=max \ --push \ -t docker.io/zhijunio/myapp:latest \ .--cache-from 指定缓存来源,--cache-to 指定缓存导出位置。mode=max 导出更多缓存层,下次构建时能更好地复用。
使用本地缓存:
# 导出到本地目录docker buildx build \ --cache-to type=local,dest=./cache \ -t myapp:latest \ .
# 从本地目录导入docker buildx build \ --cache-from type=local,src=./cache \ -t myapp:latest \ .适合本地开发时使用,缓存保存在 ./cache 目录下。
Inline 缓存(最简单):
docker buildx build \ --build-arg BUILDKIT_INLINE_CACHE=1 \ --push \ -t docker.io/zhijunio/myapp:latest \ .缓存直接内嵌在镜像层中,不需要额外配置。后续构建时会自动使用镜像中的缓存。
缓存后端类型对比:
| 类型 | 说明 | 使用场景 |
|---|---|---|
inline | 缓存内嵌在镜像层中 | 简单场景,无需额外配置 |
registry | 缓存存储在 Registry | CI/CD 共享缓存 |
local | 缓存存储到本地目录 | 本地开发 |
gha | GitHub Actions 缓存服务 | GitHub CI/CD |
多架构构建实战
构建并推送多平台镜像:
docker buildx build \ --platform linux/amd64,linux/arm64,linux/arm/v7 \ --push \ -t docker.io/zhijunio/myapp:latest \ -t docker.io/zhijunio/myapp:1.0 \ --cache-from type=registry,ref=docker.io/zhijunio/cache:myapp \ --cache-to type=registry,ref=docker.io/zhijunio/cache:myapp,mode=max \ .--platform 指定三个目标架构:amd64(常规服务器)、arm64(新 Mac)、arm/v7(树莓派)。构建完成后自动推送到 Docker Hub。
验证多架构镜像:
docker buildx imagetools inspect docker.io/zhijunio/myapp:latest输出显示镜像支持的架构列表:
Name: docker.io/zhijunio/myapp:latestMediaType: application/vnd.docker.distribution.manifest.list.v2+dockerPlatform: linux/amd64Platform: linux/arm64Platform: linux/arm/v7拉取特定架构:
docker pull --platform linux/arm64 docker.io/zhijunio/myapp:latest--platform 参数指定要拉取的架构,Docker 会自动选择匹配的镜像层。
Dockerfile 最佳实践
多阶段构建减少镜像大小:
FROM --platform=$BUILDPLATFORM golang:1.21 AS builderWORKDIR /appCOPY . .ARG TARGETOS TARGETARCHRUN GOOS=$TARGETOS GOARCH=$TARGETARCH go build -o app .
FROM alpine:latestCOPY --from=builder /app/app /appENTRYPOINT ["/app"]$BUILDPLATFORM 是构建平台的自动变量,TARGETOS和TARGETARCH 是目标平台的自动变量。这样可以在构建时自动适配不同架构。最终镜像只包含编译好的二进制文件,体积更小。
优化层缓存:
FROM node:20-alpineWORKDIR /app
# 先复制 package.json 和 package-lock.jsonCOPY package*.json ./RUN npm ci
# 再复制源代码COPY . .RUN npm run build
EXPOSE 3000CMD ["node", "dist/index.js"]依赖文件不常变化,先复制可以利用缓存。源代码经常变化,放在后面。这样修改代码时,npm ci 这层可以复用缓存。
使用 .dockerignore 排除不必要文件:
node_modulesnpm-debug.log.git.gitignoreDockerfile.dockerignoreREADME.md*.mdnode_modules 不需要,因为会重新npm install。.git 目录、文档文件也不需要进镜像。排除这些文件可以减小构建上下文,加快构建速度。
完整实战示例
Node.js 应用多平台构建:
# 创建 builder(如果还没有可用的多平台 builder)docker buildx create --name node-builder --use --bootstrap
# 构建并推送(需要先 docker login)docker buildx build \ --platform linux/amd64,linux/arm64 \ --push \ --cache-from type=registry,ref=docker.io/zhijunio/nodeapp:cache \ --cache-to type=registry,ref=docker.io/zhijunio/nodeapp:cache,mode=max \ -t docker.io/zhijunio/nodeapp:latest \ -t docker.io/zhijunio/nodeapp:1.0 \ .--bootstrap 参数会在创建 builder 后立即启动它。缓存配置可以加速后续构建。
Go 应用跨平台编译:
FROM --platform=$BUILDPLATFORM golang:1.21 AS builderWORKDIR /appCOPY . .ARG TARGETOS TARGETARCHRUN GOOS=$TARGETOS GOARCH=$TARGETARCH go build -o app .
FROM alpine:latestCOPY --from=builder /app/app /appENTRYPOINT ["/app"]docker buildx build \ --platform linux/amd64,linux/arm64 \ --push \ -t docker.io/zhijunio/goapp:latest \ .Java Spring Boot 应用:
FROM --platform=$BUILDPLATFORM eclipse-temurin:21-jdk-alpine AS builderWORKDIR /appCOPY mvnw* pom.xml ./RUN ./mvnw dependency:go-offline -BCOPY src ./srcRUN ./mvnw package -DskipTests
FROM eclipse-temurin:21-jre-alpineWORKDIR /appCOPY --from=builder /app/target/*.jar app.jarEXPOSE 8080ENTRYPOINT ["java", "-jar", "app.jar"]docker buildx build \ --platform linux/amd64,linux/arm64 \ --push \ -t docker.io/zhijunio/spring-app:latest \ .第一阶段用 JDK 编译打包,第二阶段用 JRE 运行。dependency:go-offline 预先下载依赖,利用缓存加速后续构建。
调试与排错
显示详细构建日志:
docker buildx build --progress=plain .--progress=plain 显示每个构建步骤的详细输出,方便定位问题。
查看构建器日志:
docker logs buildx_buildkit_<builder-name>0<builder-name> 替换为 builder 名称,如 multiarch-builder。
检查多架构镜像:
docker buildx imagetools inspect docker.io/zhijunio/myapp:latest拉取特定架构:
docker pull --platform linux/arm64 docker.io/zhijunio/myapp:latest常见问题
--load 报错不支持多平台:
# 错误用法(会失败)docker buildx build --platform linux/amd64,linux/arm64 --load -t myapp:latest .
# 正确用法docker buildx build --platform linux/amd64 --load -t myapp:latest .--load 只能用于单平台构建。多平台构建需要用 --push 推送到 Registry。
构建后本地找不到镜像:
docker buildx build --load -t myapp:latest .使用 docker-container 驱动时,构建结果不会自动加载到本地。添加 --load 参数或者改用 --output type=docker。
删除本地 builder:
docker buildx rm mybuilderdocker container rm -f buildx_buildkit_<name>0<name> 替换为 builder 名称。第二条命令删除 builder 对应的容器。
速查表
| 场景 | 命令 |
|---|---|
| 本地单平台测试 | docker buildx build -t img:tag . |
| 多平台 + 推送 | docker buildx build --platform linux/amd64,linux/arm64 --push -t repo/img:tag . |
| 带缓存构建 | --cache-from type=registry,ref=repo/cache --cache-to type=registry,ref=repo/cache,mode=max |
| 创建 builder | docker buildx create --name <name> --driver docker-container --use |
| 验证多平台 | docker buildx imagetools inspect repo/img:tag |
| 内联缓存 | --build-arg BUILDKIT_INLINE_CACHE=1 |
| 详细日志 | --progress=plain |
总结
Docker Buildx 主要优势:
- 多架构支持:一次构建,同时生成 amd64、arm64、arm/v7 等多个平台的镜像
- 缓存优化:支持 registry、本地、inline 等多种缓存方式,显著提升 CI/CD 构建速度
- 灵活配置:支持多种 driver 和输出方式,适应不同场景
- 易于使用:与
docker build命令兼容,学习成本低
对于需要在 ARM 架构(如 Apple Silicon、树莓派)上运行容器的开发者,Buildx 是必备工具。