记录我的一些生活写照、无聊的牢骚、内心世界的活动 注册 | 登陆

Buildx创建多平台Docker镜像

Buildx创建多平台Docker镜像
要从一个 Dockerfile 生成支持 多个平台(如 x86_64 和 ARM64)的镜像文件,你可以使用 Docker 的 Buildx 工具,它是官方提供的多平台构建解决方案。
前提条件:Docker 版本 >= 20.10
启用了 BuildKit(默认已开启):
XML/HTML代码
  1. export DOCKER_BUILDKIT=1
  2. 或者
  3. export DOCKER_CLI_EXPERIMENTAL=enabled
验证是否开启: 
XML/HTML代码
  1. docker buildx version
步骤:构建多平台镜像
1. 创建 buildx builder 实例(只需一次):
XML/HTML代码
  1. docker buildx create --name multi-builder --use
  2. docker buildx inspect --bootstrap
如果你已经有 builder,可以跳过。
2. 构建并导出镜像文件(例如 .tar):
方法一:构建并导出为 .tar 文件(本地导出,适合离线使用)
XML/HTML代码
  1. docker buildx build \
  2.   --platform linux/arm64 \
  3.   --output type=docker,dest=multi-platform-image.tar \
  4.   -t myimage:latest \
  5.   -f Dockerfile .
输出类型为 docker 只支持 单平台导出,所以多平台导出推荐使用 type=oci 或 type=image:
XML/HTML代码
  1. docker buildx build \
  2.   --platform linux/amd64,linux/arm64 \
  3.   --output "type=oci,dest=multi-platform.oci" \
  4.   -t myimage:latest \ 
  5.   -f Dockerfile .
3. 或者直接推送到 Docker Hub(支持多平台)
登录 Docker Hub
使用以下命令登录 Docker Hub:
XML/HTML代码
  1. docker login
镜像名称必须以你的用户名开头
Docker Hub 上的免费仓库命名规则:用户名/仓库名
你的镜像名是 aaa/myimage:latest,必须保证:
你在 Docker Hub 上的用户名是 aaa
仓库名为 myimage,必须已创建或首次推送时自动创建(公共仓库)
否则你没有权限推送这个镜像。
XML/HTML代码
  1. docker login
  2. docker buildx build \
  3.   --platform linux/amd64,linux/arm64 \
  4.   -t yourname/myimage:latest \
  5.   --push \
  6.   -f Dockerfile .
验证
推送完成后可以通过以下方式验证镜像 
XML/HTML代码
  1. docker pull aaa/myimage:latest
常见平台标识
XML/HTML代码
  1. 平台名称          描述
  2. linux/amd64   64-bit x86 平台
  3. linux/arm64   64-bit ARM(如树莓派4)
  4. linux/arm/v7  32-bit ARM
  5. linux/386     32-bit x86
验证镜像架构
如果你已经导出 .oci 文件:
XML/HTML代码
  1. tar -tvf multi-platform.oci
如果你推送到了仓库,可以用 Docker Hub 或 Skopeo 来查看:
XML/HTML代码
  1. skopeo inspect docker://yourname/myimage:latest
小提示
如果你想单独构建某个平台的镜像为 .tar 文件:
XML/HTML代码
  1. docker buildx build \
  2.   --platform linux/arm64 \
  3.   --output type=docker,dest=arm64-image.tar \
  4.   -t myimage:arm64 \
  5.   .
加快构建速度:推荐使用 --cache-to 和 --cache-from。
自己DIY的一键生成&推送脚本
XML/HTML代码
  1. #!/bin/bash  
  2. set -e  
  3.   
  4. # ============ 可选平台 =============  
  5. PLATFORM_LIST=(  
  6.   "linux/amd64 (x86_64)"  
  7.   "linux/arm64 (ARMv8)"  
  8.   "linux/arm/v7 (ARMv7 32-bit)"  
  9. )  
  10. PLATFORM_KEYS=(  
  11.   "linux/amd64"  
  12.   "linux/arm64"  
  13.   "linux/arm/v7"  
  14. )  
  15.   
  16. # ============ 默认变量 =============  
  17. IMAGE_NAME="myimage"  
  18. IMAGE_TAG="latest"  
  19. DOCKERFILE="Dockerfile"  
  20. TAR_NAME="image.tar"  
  21. BUILD_MODE="local"  
  22. PLATFORMS=""  
  23.   
  24. # ============ 平台选择菜单 ============  
  25. select_platforms() {  
  26.   while true; do  
  27.     echo ""  
  28.     echo "请选择要构建的平台(可多选,用空格分隔,例如 1 2):"  
  29.     for i in "${!PLATFORM_LIST[@]}"; do  
  30.       echo "$((i+1)). ${PLATFORM_LIST[$i]}"  
  31.     done  
  32.   
  33.     read -p "选择平台: " PLATFORM_SELECTION  
  34.   
  35.     SELECTED_PLATFORMS=()  
  36.     for index in $PLATFORM_SELECTION; do  
  37.       if [[ $index -ge 1 && $index -le ${#PLATFORM_KEYS[@]} ]]; then  
  38.         SELECTED_PLATFORMS+=("${PLATFORM_KEYS[$((index-1))]}")  
  39.       else  
  40.         echo "⚠️  无效平台编号: $index"  
  41.         exit 1  
  42.       fi  
  43.     done  
  44.   
  45.     PLATFORMS=$(IFS=','; echo "${SELECTED_PLATFORMS[*]}")  
  46.     break  
  47.   done  
  48. }  
  49.   
  50. # ============ 构建模式菜单 ============  
  51. select_build_mode() {  
  52.   echo ""  
  53.   echo "请选择构建模式:"  
  54.   echo "1. 本地构建并导入镜像(不推送)"  
  55.   echo "2. 构建并导出为 tar 文件(仅支持单平台)"  
  56.   echo "3. 构建并推送到远程仓库"  
  57.   
  58.   while true; do  
  59.     read -p "输入选项 [1-3]: " MODE  
  60.     case $MODE in  
  61.       1) BUILD_MODE="local"; break;;  
  62.       2)  
  63.         BUILD_MODE="export"  
  64.         if [[ "$PLATFORMS" == *,* ]]; then  
  65.           echo "❌ 导出模式只支持单平台。请重新选择一个平台。"  
  66.           select_platforms  
  67.         fi  
  68.         read -p "导出 tar 文件名(默认: $TAR_NAME): " INPUT_TAR  
  69.         [[ -n "$INPUT_TAR" ]] && TAR_NAME="$INPUT_TAR"  
  70.         break;;  
  71.       3) BUILD_MODE="push"; break;;  
  72.       *) echo "❌ 无效选项,请输入 1 ~ 3";;  
  73.     esac  
  74.   done  
  75. }  
  76.   
  77. # ============ 输入镜像信息 ============  
  78. input_image_info() {  
  79.   read -p "镜像名称(默认: $IMAGE_NAME): " INPUT_NAME  
  80.   [[ -n "$INPUT_NAME" ]] && IMAGE_NAME="$INPUT_NAME"  
  81.   
  82.   read -p "镜像标签(默认: $IMAGE_TAG): " INPUT_TAG  
  83.   [[ -n "$INPUT_TAG" ]] && IMAGE_TAG="$INPUT_TAG"  
  84.   
  85.   read -p "Dockerfile 路径(默认: $DOCKERFILE): " INPUT_DF  
  86.   [[ -n "$INPUT_DF" ]] && DOCKERFILE="$INPUT_DF"  
  87.   
  88.   # 自动修复 Dockerfile 路径  
  89.   if [[ -d "$DOCKERFILE" ]]; then  
  90.     if [[ -f "$DOCKERFILE/Dockerfile" ]]; then  
  91.       echo "⚠️ 检测到你输入的是目录,自动使用: $DOCKERFILE/Dockerfile"  
  92.       DOCKERFILE="$DOCKERFILE/Dockerfile"  
  93.     else  
  94.       echo "❌ 无法在目录中找到 Dockerfile: $DOCKERFILE/Dockerfile"  
  95.       exit 1  
  96.     fi  
  97.   elif [[ ! -f "$DOCKERFILE" ]]; then  
  98.     echo "❌ 指定的 Dockerfile 文件不存在: $DOCKERFILE"  
  99.     exit 1  
  100.   fi  
  101. }  
  102.   
  103. # ============ 初始化 builder ============  
  104. init_builder() {  
  105.   if ! docker buildx inspect multi-builder &>/dev/null; then  
  106.     echo "???? 创建 buildx builder..."  
  107.     docker buildx create --name multi-builder --use  
  108.     docker buildx inspect --bootstrap  
  109.   else  
  110.     docker buildx use multi-builder  
  111.   fi  
  112. }  
  113.   
  114. # ============ 执行构建 ============  
  115. run_build() {  
  116.   echo ""  
  117.   echo "???? 构建平台: $PLATFORMS"  
  118.   echo "???? Dockerfile: $DOCKERFILE"  
  119.   echo "???? 镜像: $IMAGE_NAME:$IMAGE_TAG"  
  120.   
  121.   if [[ "$BUILD_MODE" == "push" ]]; then  
  122.     docker buildx build --platform "$PLATFORMS" -t "$IMAGE_NAME:$IMAGE_TAG" -f "$DOCKERFILE" . --push  
  123.   elif [[ "$BUILD_MODE" == "export" ]]; then  
  124.     docker buildx build --platform "$PLATFORMS" -t "$IMAGE_NAME:$IMAGE_TAG" -f "$DOCKERFILE" . \  
  125.       --output "type=docker,dest=$TAR_NAME"  
  126.     echo "✅ 导出完成: $TAR_NAME (平台: $PLATFORMS)"  
  127.   else  
  128.     docker buildx build --platform "$PLATFORMS" -t "$IMAGE_NAME:$IMAGE_TAG" -f "$DOCKERFILE" . --load  
  129.   fi  
  130.   echo "✅ 构建完成。"  
  131. }  
  132.   
  133. # ============ 主程序 ============  
  134. echo "=== 多平台 Docker 构建工具 ==="  
  135. select_platforms  
  136. select_build_mode  
  137. input_image_info  
  138. init_builder  
  139. run_build  

« 上一篇 | 下一篇 »

发表评论

评论内容 (必填):