← 中文资源

简体中文版本

Docker 构建打标推送健康检查

脚本化完整容器发布流:SHA 标签与 OCI 标注齐备、digest 校验推送结果、manifest 探测循环等待 registry 就绪才算完成。

阅读英文原文

示例说明

手工 docker build/tag/push 三连容易漏标签或推错仓——脚本把流程钉死。镜像标签以 git SHA 为主键:可追溯回具体提交,latest 只是移动指针;构建参数与 OCI 标准标签把修订号与时间写进镜像元数据,registry 里可查。推送后的 digest 是不可变指纹,manifest 探测确认多架构清单在 registry 真正就绪——推送命令成功不等于立即可拉。

技术要点

  • git SHA 作为镜像主标签可追溯
  • OCI 标准标签内建镜像元数据
  • manifest 探测确认 registry 就绪

代码解读

前置检查包括 docker 存在与工作区干净——脏工作区构建的镜像无法对应任何提交;build 传修订号构建参数并打两个标签。push_and_verify 推送后从 RepoDigests 提取 digest 展示,manifest inspect 的 until 循环最多五次每次三秒——多架构镜像的 manifest 聚合有延迟。

使用建议

latest 标签仅作便捷指针,部署清单永远钉 SHA 或 digest。构建缓存与多架构构建按 CI 能力叠加。registry 凭据走 docker login 的外部配置。

代码示例

#!/usr/bin/env bash
set -euo pipefail

readonly REGISTRY="registry.example.com"
readonly IMAGE="${REGISTRY}/billing-api"
readonly GIT_SHA="$(git rev-parse --short=12 HEAD)"

die() { echo "Error: $*" >&2; exit 1; }

command -v docker >/dev/null || die "docker 未安装"
git diff --quiet || die "工作区不干净,先提交再发布"

build() {
  echo "构建 ${IMAGE}:${GIT_SHA}"
  docker build \
    --build-arg GIT_COMMIT="${GIT_SHA}" \
    --label "org.opencontainers.image.revision=${GIT_SHA}" \
    --label "org.opencontainers.image.created=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
    -t "${IMAGE}:${GIT_SHA}" \
    -t "${IMAGE}:latest" \
    .
}

push_and_verify() {
  docker push "${IMAGE}:${GIT_SHA}"
  docker push "${IMAGE}:latest"

  local digest
  digest=$(docker inspect --format '{{index .RepoDigests 0}}' \
    "${IMAGE}:${GIT_SHA}" | cut -d@ -f2)
  echo "已推送: ${IMAGE}@${digest}"

  # registry 健康探测:清单可拉取才算发布完成
  local attempt=0
  until docker manifest inspect "${IMAGE}:${GIT_SHA}" >/dev/null 2>&1; do
    (( attempt++ )) || true
    (( attempt < 5 )) || die "manifest 未就绪,registry 可能异常"
    sleep 3
  done
  echo "发布完成:${GIT_SHA}"
}

build
push_and_verify