一、脚本能力拆分

1.1 目录中包含的两类脚本

  • foreign_to_alibaba_docker.sh:适合处理单个镜像地址。
  • foreign_to_alibaba_docker_batch.sh:适合一次输入多个镜像,统一完成登录、拉取、改标签和推送。

1.2 适用场景

  • 海外镜像访问慢,需要同步到国内仓库。
  • 业务环境只能从阿里云私有仓库拉取镜像。
  • 需要临时构建“镜像白名单”或镜像缓存目录。

二、批量同步的核心流程

2.1 自动安装 Docker 并启动服务

if command -v docker &> /dev/null; then
    echo "Docker 已安装"
else
    yum install -y docker
    systemctl start docker
    systemctl enable docker
fi

2.2 输入镜像并重打标签

read -p "请输入完整镜像地址,多个镜像用空格隔开: " -a images_input
read -p "请输入阿里云镜像仓库用户名: " username
read -sp "请输入阿里云镜像仓库密码: " password

echo "$password" | docker login --username="$username" --password-stdin registry.cn-hangzhou.aliyuncs.com
docker pull docker.io/bitnami/redis:7.2.4
docker tag docker.io/bitnami/redis:7.2.4 registry.cn-hangzhou.aliyuncs.com/<namespace>/redis:7.2.4
docker push registry.cn-hangzhou.aliyuncs.com/<namespace>/redis:7.2.4

三、整理成博客时值得强调的点

3.1 这类脚本的价值不只是“搬运镜像”

  • 统一镜像命名空间,方便后续业务引用。
  • 为封网环境提前准备基础镜像。
  • 可以扩展成“批量镜像同步 + 清单文件”的方式。

3.2 建议改造为可复用参数

  • 仓库域名建议抽成变量,例如 REGISTRY_HOST
  • 命名空间建议抽成 REGISTRY_NAMESPACE
  • 失败重试、推送结果校验、日志输出建议单独增强。

四、完整脚本

以下为本文对应的完整脚本,便于直接复制复用。

4.1 foreign_to_alibaba_docker.sh

#!/bin/bash

# 输出分隔符和颜色配置
separator="----------"
color_green='\033[0;32m'
color_red='\033[0;31m'
color_reset='\033[0m'

# 判断 Docker 是否已经安装
if command -v docker &> /dev/null; then
    echo -e "${color_green}$separator Docker 之前已安装完成 $separator${color_reset}"
else
    # 安装 Docker(隐藏输出)
    echo -e "${color_green}$separator 安装 Docker 开始 $separator${color_reset}"
    yum install -y docker > /dev/null 2>&1
    docker --version > /dev/null 2>&1
    systemctl start docker > /dev/null 2>&1 && systemctl enable docker > /dev/null 2>&1

    # 判断 Docker 是否安装成功
    if ! command -v docker &> /dev/null; then
        echo -e "${color_red}$separator Docker 安装失败,请检查错误 $separator${color_reset}"
        exit 1
    else
        echo -e "${color_green}$separator Docker 安装成功 $separator${color_reset}"
    fi
fi

# 输入镜像名称和版本
read -p "请输入完整的镜像地址(如docker.io/bitnami/redis:7.2.4-debian-12-r9): " image_input

# 提取镜像名称和版本,默认版本为latest
if [[ "$image_input" =~ /([^:/]+)(:([a-zA-Z0-9.-]+))?$ ]]; then
    image_name="${BASH_REMATCH[1]}"
    image_tag="${BASH_REMATCH[3]:-latest}"  # 如果没有输入版本号,默认使用latest
else
    echo -e "${color_red}$separator 输入格式有误,请提供完整的镜像地址。 $separator${color_reset}"
    exit 1
fi

# 输出提取结果
echo -e "${color_green}$separator 拉取镜像: $image_input $separator${color_reset}"
echo -e "${color_green}$separator 镜像名称: $image_name $separator${color_reset}"
echo -e "${color_green}$separator 镜像版本: $image_tag $separator${color_reset}"

# 拉取镜像
echo -e "${color_green}$separator 拉取镜像中... $separator${color_reset}"
docker pull $image_input > /dev/null 2>&1

# 打标签
echo -e "${color_green}$separator 修改标签为阿里云镜像 $separator${color_reset}"
docker tag $image_input registry.cn-hangzhou.aliyuncs.com/abroad_images/$image_name:$image_tag > /dev/null 2>&1

# 登录阿里云镜像仓库
echo -e "${color_green}$separator 请登录阿里云镜像仓库 $separator${color_reset}"
read -p "请输入阿里云镜像仓库用户名: " username
read -sp "请输入阿里云镜像仓库密码: " password
echo

# 登录操作(只需要执行一次)
echo $password | docker login --username=$username --password-stdin registry.cn-hangzhou.aliyuncs.com > /dev/null 2>&1

# 判断是否登录成功
if [ $? -eq 0 ]; then
    echo -e "${color_green}$separator 登录成功,开始推送镜像 $separator${color_reset}"
else
    echo -e "${color_red}$separator 登录失败,请检查用户名和密码 $separator${color_reset}"
    exit 1
fi

# 推送镜像
echo -e "${color_green}$separator 推送镜像到阿里云 $separator${color_reset}"
docker push registry.cn-hangzhou.aliyuncs.com/abroad_images/$image_name:$image_tag > /dev/null 2>&1

echo -e "${color_green}$separator 镜像推送完成 $separator${color_reset}"

4.2 foreign_to_alibaba_docker_batch.sh

#!/bin/bash

# 输出分隔符和颜色配置
separator="----------"
color_green='\033[0;32m'
color_red='\033[0;31m'
color_reset='\033[0m'

# 判断 Docker 是否已经安装
if command -v docker &> /dev/null; then
    echo -e "${color_green}$separator Docker 之前已安装完成 $separator${color_reset}"
else
    # 安装 Docker(隐藏输出)
    echo -e "${color_green}$separator 安装 Docker 开始 $separator${color_reset}"
    yum install -y docker > /dev/null 2>&1
    docker --version > /dev/null 2>&1
    systemctl start docker > /dev/null 2>&1 && systemctl enable docker > /dev/null 2>&1

    # 判断 Docker 是否安装成功
    if ! command -v docker &> /dev/null; then
        echo -e "${color_red}$separator Docker 安装失败,请检查错误 $separator${color_reset}"
        exit 1
    else
        echo -e "${color_green}$separator Docker 安装成功 $separator${color_reset}"
    fi
fi

# 输入多个镜像地址
read -p "请输入完整的镜像地址(如docker.io/bitnami/redis:7.2.4-debian-12-r9),多个镜像地址请用空格隔开: " -a images_input

# 登录阿里云镜像仓库
echo -e "${color_green}$separator 请登录阿里云镜像仓库 $separator${color_reset}"
read -p "请输入阿里云镜像仓库用户名: " username
read -sp "请输入阿里云镜像仓库密码: " password
echo

# 登录操作(只需要执行一次)
echo $password | docker login --username=$username --password-stdin registry.cn-hangzhou.aliyuncs.com > /dev/null 2>&1

# 判断是否登录成功
if [ $? -eq 0 ]; then
    echo -e "${color_green}$separator 登录成功,开始拉取并推送镜像 $separator${color_reset}"
else
    echo -e "${color_red}$separator 登录失败,请检查用户名和密码 $separator${color_reset}"
    exit 1
fi

# 遍历每个镜像,拉取并推送到阿里云
for image_input in "${images_input[@]}"; do
    # 提取镜像名称和版本,默认版本为latest
    if [[ "$image_input" =~ /([^:/]+)(:([a-zA-Z0-9.-]+))?$ ]]; then
        image_name="${BASH_REMATCH[1]}"
        image_tag="${BASH_REMATCH[3]:-latest}"  # 如果没有输入版本号,默认使用latest
    else
        echo -e "${color_red}$separator 输入格式有误,请提供完整的镜像地址。 $separator${color_reset}"
        continue
    fi

    # 输出提取结果
    echo -e "${color_green}$separator 拉取镜像: $image_input $separator${color_reset}"
    echo -e "${color_green}$separator 镜像名称: $image_name $separator${color_reset}"
    echo -e "${color_green}$separator 镜像版本: $image_tag $separator${color_reset}"

    # 拉取镜像
    echo -e "${color_green}$separator 拉取镜像中... $separator${color_reset}"
    docker pull $image_input > /dev/null 2>&1

    # 打标签
    echo -e "${color_green}$separator 修改标签为阿里云镜像 $separator${color_reset}"
    docker tag $image_input registry.cn-hangzhou.aliyuncs.com/abroad_images/$image_name:$image_tag > /dev/null 2>&1

    # 推送镜像
    echo -e "${color_green}$separator 推送镜像到阿里云 $separator${color_reset}"
    docker push registry.cn-hangzhou.aliyuncs.com/abroad_images/$image_name:$image_tag > /dev/null 2>&1

    echo -e "${color_green}$separator 镜像推送完成 $separator${color_reset}"
done

echo -e "${color_green}$separator 所有镜像推送完成 $separator${color_reset}"