#!/usr/bin/env bash # ========================================================= # Arcticnewone 镜像构建与推送脚本(本地 / 部署服务器手动执行) # # 遵循团队部署规范: # - 镜像推送到华为云 SWR,tag 固定为 latest # - 多架构:linux/amd64 + linux/arm64 # - 分架构推送(latest-amd64 / latest-arm64),再用 docker manifest # 合并为 latest(标准 Docker manifest list,SWR 可正常解析) # - --provenance=false 禁用 SLSA 证明,避免额外 manifest # - 登录凭据一律从环境变量读取,绝不写入仓库 # # 使用前先设置环境变量(示例): # export SWR_REGISTRY="swr.cn-north-4.myhuaweicloud.com" # export SWR_NAMESPACE="virtheart" # export SWR_USERNAME="" # export SWR_PASSWORD="" # 然后执行: # ./build-and-push.sh # ========================================================= set -euo pipefail # 必填环境变量校验(缺失即报错退出) : "${SWR_REGISTRY:?请先设置环境变量 SWR_REGISTRY(例如 swr.cn-north-4.myhuaweicloud.com)}" : "${SWR_NAMESPACE:?请先设置环境变量 SWR_NAMESPACE(例如 virtheart)}" : "${SWR_USERNAME:?请先设置环境变量 SWR_USERNAME(SWR 登录用户名)}" : "${SWR_PASSWORD:?请先设置环境变量 SWR_PASSWORD(SWR 登录密码)}" IMAGE_NAME="arcticnewone" IMAGE_TAG="latest" FULL_IMAGE="${SWR_REGISTRY}/${SWR_NAMESPACE}/${IMAGE_NAME}:${IMAGE_TAG}" ARCHS="amd64 arm64" BUILDER_NAME="multiarch-builder" # 前置检查:docker / buildx / manifest if ! command -v docker >/dev/null 2>&1; then echo "错误: 未找到 docker 命令,请先安装 Docker" >&2 exit 1 fi if ! docker buildx version >/dev/null 2>&1; then echo "错误: 未找到 docker buildx,请启用 Buildx(Docker 20.10+ 默认内置)" >&2 exit 1 fi if ! docker manifest --help >/dev/null 2>&1; then echo "错误: 当前 Docker 不支持 docker manifest 命令" >&2 exit 1 fi # 1. 登录 SWR(凭据来自环境变量,不写入仓库) echo ">>> [1/4] 登录 SWR: ${SWR_REGISTRY}" echo "${SWR_PASSWORD}" | docker login "${SWR_REGISTRY}" -u "${SWR_USERNAME}" --password-stdin # 2. 确保支持多架构的 builder 存在 echo ">>> [2/4] 准备多架构 builder: ${BUILDER_NAME}" if ! docker buildx inspect "${BUILDER_NAME}" >/dev/null 2>&1; then docker buildx create --name "${BUILDER_NAME}" fi # 3. 分别构建并推送各架构镜像(禁用 provenance,产物为单一 manifest) for ARCH in ${ARCHS}; do echo ">>> [3/4] 构建并推送 linux/${ARCH}: ${FULL_IMAGE}-${ARCH}" docker buildx build \ --builder "${BUILDER_NAME}" \ --platform "linux/${ARCH}" \ --provenance=false \ --push \ -t "${FULL_IMAGE}-${ARCH}" \ . done # 4. 合并为多架构 manifest list 并推送(标准 Docker manifest list) echo ">>> [4/4] 合并并推送多架构 manifest: ${FULL_IMAGE}" docker manifest create "${FULL_IMAGE}" \ --amend "${FULL_IMAGE}-amd64" \ --amend "${FULL_IMAGE}-arm64" docker manifest push "${FULL_IMAGE}" echo ">>> 推送完成: ${FULL_IMAGE} (linux/amd64 + linux/arm64)"