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/amd64 和 linux/arm64 双架构镜像,并自动推送到 DockerHub 镜像仓库。
功能特点
- 支持交互式和传参两种模式(可指定项目目录、镜像名称、DockerHub 密码)
- 自动初始化 buildx 构建器,创建 mybuilder 构建实例
- 加载 QEMU 跨架构模拟支持,确保 arm64 镜像可正常构建
- 自动登录 DockerHub 并推送镜像
- 构建前清理 Docker 无用资源
- 自动生成日期标签(如
2026.06.09)并同时推送latest标签 - 支持多平台构建:linux/amd64 + linux/arm64
工作流程
项目源码目录
↓
初始化 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 无用资源 |
| 构建信息 | 显示构建平台和标签 |
| 构建结果 | 构建完成后的镜像地址 |
注意事项
- 脚本需要 root 权限或 docker 命令执行权限
- 项目目录必须包含有效的 Dockerfile
- 首次运行会创建 mybuilder 构建器,后续直接复用
- 需提前在 DockerHub 创建好对应仓库
- 建议使用 DockerHub Access Token(
dckr_pat_xxxxxx)替代密码登录 - 跨架构构建耗时较长,请耐心等待
- DockerHub 密码为密文输入,不回显在终端
- 传参模式直接传入密码时,密码会出现在进程列表中,生产环境建议交互式输入
脚本源码
#!/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"