tags: [docker, build, buildx] —

构建多架构镜像

https://docs.docker.com/build/building/multi-platform/

为了同名镜像适配不同的操作系统,需要构建多架构镜像。 需要使用 docker buildx。buildx 会在指定构建器实例中构建镜像。

docker buildx

https://docs.docker.com/build/buildkit/

在 docker 18.09 版本之后,用户可以使用 docker buildx 命令。

它有以下功能,

  • 检测并跳过执行未使用的构建阶段
  • 平行化构建独立的构建阶段
  • 在两次构建之间,只递增传输构建环境中已更改的文件
  • 检测并跳过传输构建环境中未使用的文件
  • 使用具有许多新功能的 Dockerfile 前端实现
  • 避免与其他API(中间镜像和容器)产生副作用
  • 对你的构建缓存进行优先排序,以便自动修剪

BuildKit 默认为 Docker Desktop 上的所有用户启用。如果你已经安装了 Docker Desktop,你就不需要手动启用 BuildKit。 如果你在 Linux 上运行 Docker,你可以通过使用环境变量 DOCKER_BUILDKIT=1,或将 BuildKit 作为默认设置来启用 BuildKit。

docker buildx commands: bake Build from a file build Start a build create Create a new builder instance du Disk usage inspect Inspect current builder instance ls List builder instances prune Remove build cache rm Remove a builder instance stop Stop builder instance use Set the current builder instance version Show buildx version information

builder

当前的构建器实例 (builder) 的 driver 是 docker-container 或者 kubernetes 时,可以构建多架构镜像。 默认的 default builder 是 docker driver,而不是 docker-container driver。

所以你要用 docker buildx create 创建自己的构建器实例。--driver docker-container 是默认参数,会创建一个基于 moby/buildkit 镜像的容器。在这个容器中构建多架构镜像。

  • docker buildx create --name $BUILDER --bootstrap --use 创建 builder 实例,并使用这个实例。
  • docker buildx ls 列出所有 builder 实例。
  • docker buildx use 切换 builder 实例。
  • docker buildx inspect 查看当前 builder 实例信息。

docker buildx build

docker buildx build --platform linux/amd64,linux/arm64,linux/386,linux/arm/v7,linux/arm/v6 --push --tag owner/image:version .

在这种情况下,它会建立一个清单 (manifest),其中包含所有指定架构的镜像。 当你在 docker run 或 docker service 中使用这个镜像时,Docker 会根据节点的平台来挑选正确的镜像。

注意,不能分开使用 --platform,比如先执行 docker buildx build --platform linux/amd64,后执行 docker buildx build --platform linux/arm64。后面构建的镜像会覆盖之前的镜像,最终只会产生单架构的镜像。

注意,用户必须加上 --push 参数,它会自动 push 构建好的镜像到 docker hub。由于 docker buildx build 构建的多架构的镜像只会保留最后一份架构的镜像在本机,用户没法用 docker push 来提交多架构镜像。

详见 https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md

TARGETPLATFORM 变量

--platform 传递的参数会自动注入到 TARGETPLATFORM 环境变量里。 方便在 RUN heredoc 里使用条件判断。

FROM alpine
ARG TARGETPLATFORM
RUN echo "I'm building for $TARGETPLATFORM"

详见 https://docs.docker.com/reference/dockerfile/#automatic-platform-args-in-the-global-scope