随机
Enter 搜索 ↑↓ 切换 Esc 清空

cmdbox_docker_buildx

脚本

Docker Buildx 多架构镜像构建与自动推送

cmdbox_docker_buildx

Docker Buildx 多架构镜像构建与自动推送

一键脚本

bash <(curl -sL gitee.com/meimolihan/cmdbox/raw/master/sh/cmdbox_docker_buildx.sh) dckr_pat_xxxxxx
bash <(curl -sL ../sh/cmdbox_docker_buildx.sh) dckr_pat_xxxxxx
模式 命令 说明
交互模式 脚本.sh 交互式输入项目目录、镜像名称和 DockerHub 密码
传参模式 脚本.sh dckr_pat_xxxxxx 直接传入 DockerHub 密码,其余使用默认值

效果预览

执行脚本效果预览

补充说明

该脚本用于 Cmdbox 项目的 Docker Buildx 多架构镜像构建与自动推送。通过 Docker Buildx 同时构建 linux/amd64linux/arm64 双架构镜像,并自动推送到 DockerHub 镜像仓库。

功能特点

工作流程

项目源码目录
初始化 buildx 构建器
加载 QEMU 跨架构模拟
登录 DockerHub
docker buildx build --platform linux/amd64,linux/arm64
推送至 DockerHub(latest + 日期标签)

参数说明

参数 说明
第1个参数 DockerHub 密码或 Access Token(格式:dckr_pat_xxxxxx

交互模式下会依次提示输入:

提示项 默认值 说明
项目目录 /vol1/1000/GitHub/cmdbox-main 包含 Dockerfile 的源码目录
镜像名称 mobufan/cmdbox DockerHub 镜像仓库名
DockerHub 密码 DockerHub 密码或 Access Token(密文输入)

输出说明

字段 说明
工作目录校验 检查源码目录是否存在
buildx 构建器 初始化 mybuilder 构建实例
QEMU 跨架构模拟 加载 arm64 模拟支持
DockerHub 登录 登录 DockerHub 镜像仓库
资源清理 清理 Docker 无用资源
构建信息 显示构建平台和标签
构建结果 构建完成后的镜像地址

注意事项

脚本源码

#!/bin/bash
set -euo pipefail

list_color_init() {
    export gl_hui=$'\033[38;5;59m'
    export gl_hong=$'\033[38;5;9m'
    export gl_lv=$'\033[38;5;10m'
    export gl_huang=$'\033[38;5;11m'
    export gl_lan=$'\033[38;5;32m'
    export gl_bai=$'\033[38;5;15m'
    export gl_zi=$'\033[38;5;13m'
    export gl_bufan=$'\033[38;5;14m'
    export reset=$'\033[0m'
}
list_color_init

log_info()  { echo -e "${gl_lan}[信息]${gl_bai} $*"; }
log_ok()    { echo -e "${gl_lv}[成功]${gl_bai} $*"; }
log_warn()  { echo -e "${gl_huang}[警告]${gl_bai} $*"; }
log_error() { echo -e "${gl_hong}[错误]${gl_bai} $*" >&2; }

sleep_fractional() {
    local seconds=$1
    if sleep "$seconds" 2>/dev/null; then return 0; fi
    if command -v perl >/dev/null 2>&1; then perl -e "select(undef, undef, undef, $seconds)"; return 0; fi
    if command -v python3 >/dev/null 2>&1; then python3 -c "import time; time.sleep($seconds)"; return 0; fi
    if command -v python >/dev/null 2>&1; then python -c "import time; time.sleep($seconds)"; return 0; fi
    local int_seconds=$(echo "$seconds" | awk '{print int($1+0.999)}')
    sleep "$int_seconds"
}

handle_invalid_input() {
    echo -ne "\r\033[K${gl_huang}无效的输入,请重新输入! ${gl_zi} 1 ${gl_huang} 秒后返回"
    sleep_fractional 1
    echo -ne "\r\033[K${gl_lv}无效的输入,请重新输入! ${gl_zi}0${gl_lv} 秒后返回"
    sleep_fractional 0.5
    echo -ne "\r\033[K"
    return 2
}

break_end() {
    echo -e "${gl_lv}操作完成${gl_bai}"
    echo -e "${gl_bai}按任意键继续 ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai} \c"
    read -r -n 1 -s -r -p ""
    echo ""
    clear
}

main() {
    local DEFAULT_DIR="/vol1/1000/GitHub/cmdbox-main"
    local DEFAULT_IMG="mobufan/cmdbox"
    local BUILDER_NAME="mybuilder"
    local PLATFORMS="linux/amd64,linux/arm64"
    local DOCKER_PWD=""
    local WORK_DIR=""
    local IMAGE_FULL=""

    clear
    echo -e "${gl_zi}>>> 多架构镜像自动构建推送${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    if [ $# -ge 1 ]; then
        DOCKER_PWD="$1"
        WORK_DIR="${DEFAULT_DIR}"
        IMAGE_FULL="${DEFAULT_IMG}"
        log_info "检测到传入密码参数,使用默认配置执行"
    else
        read -r -e -p "$(echo -e "${gl_bai}请输入项目目录 (回车使用默认 ${gl_huang}${DEFAULT_DIR}${gl_bai}): ")" input_dir
        WORK_DIR="${input_dir:-${DEFAULT_DIR}}"

        read -r -e -p "$(echo -e "${gl_bai}请输入镜像名称 (回车使用默认 ${gl_huang}${DEFAULT_IMG}${gl_bai}): ")" input_img
        IMAGE_FULL="${input_img:-${DEFAULT_IMG}}"

        read -r -s -p "$(echo -e "${gl_bai}请输入DockerHub密码 (格式参考 ${gl_huang}dckr_pat_xxxxxx${gl_bai}): ")" DOCKER_PWD
        echo ""
    fi

    log_info "校验工作目录 ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    if [ ! -d "${WORK_DIR}" ]; then
        log_error "工作目录不存在:${WORK_DIR}"
        break_end
        exit 1
    fi
    cd "${WORK_DIR}"

    log_info "初始化 buildx 构建器 ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    docker buildx use "${BUILDER_NAME}" 2>/dev/null || docker buildx create --name "${BUILDER_NAME}" --use

    log_info "加载 QEMU 跨架构模拟支持 ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    docker buildx inspect "${BUILDER_NAME}" --bootstrap

    echo -e ""
    echo -e "${gl_huang}>>> 登录 DockerHub 镜像仓库 ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo "${DOCKER_PWD}" | docker login -u mobufan --password-stdin

    echo -e ""
    echo -e "${gl_huang}>>> 清理 Docker 无用资源 ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    docker system prune -f

    local BUILD_TAG=$(date +%Y.%m.%d)
    echo -e ""
    echo -e "${gl_huang}>>> 开始构建镜像 ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    echo -e "${gl_bai}  平台:${gl_lv}${PLATFORMS}${gl_bai}"
    echo -e "${gl_bai}  标签:${gl_lv}latest ${gl_bai}/ ${gl_lv}${BUILD_TAG}${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    docker buildx build \
        --platform "${PLATFORMS}" \
        --no-cache \
        -t "${IMAGE_FULL}:latest" \
        -t "${IMAGE_FULL}:${BUILD_TAG}" \
        --push \
        .

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    log_ok "镜像构建推送完成!"
    log_ok "镜像地址:${gl_lv}${IMAGE_FULL}:latest ${gl_bai}${gl_lv}${IMAGE_FULL}:${BUILD_TAG}${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    break_end
}

main "$@"

创建本地脚本

new_script="new_test.sh"

cat > "$new_script" << 'EOF'
#!/bin/bash

# 粘贴脚本源码

EOF

# 保留本地脚本,去掉 rm -f "$new_script"
chmod +x "$new_script" && ./"$new_script" && rm -f "$new_script"

相关命令