Docker Hub 镜像一键同步至阿里云 ACR


🐳 Docker Hub 镜像一键同步至阿里云 ACR

本脚本用于 从 Docker Hub 拉取镜像并推送到阿里云容器镜像服务(ACR)

它通过 Python 的 docker SDK 封装了完整流程:拉取 → 重命名 → 登录 → 推送,并在控制台实时输出进度日志,方便运维和开发人员快速完成镜像同步。

✨ 功能特点

  • 支持从 Docker Hub 拉取任意镜像(如 nginx:latest
  • 自动重命名为 阿里云 ACR 标准镜像格式
  • 支持 公网地址内网 VPC 地址 两种形式
  • 全过程输出拉取、推送进度,方便排错
  • 命令行参数友好,可灵活调用

🚀 使用方法

  1. 确保本地安装了 Docker 并已启动

  2. 安装依赖:

    bash 复制代码
    pip install docker
  3. 执行脚本(例如拉取 nginx:latest):

    bash 复制代码
    python ack-reg-sync.py nginx:latest

⚙️ 配置说明

在脚本中可修改以下固定参数:

  • acr_registry:阿里云 ACR 地址(如 registry.cn-shenzhen.aliyuncs.com
  • acr_namespace:命名空间(仓库名)
  • acr_username:阿里云账号或 RAM 用户
  • acr_password:对应密码或临时令牌
py 复制代码
import docker
import argparse  # 新增导入

def pull_from_dockerhub_and_push_to_acr(
    dockerhub_image: str,
    acr_registry: str,
    acr_namespace: str,
    acr_username: str,
    acr_password: str
):
    """
    从 Docker Hub 拉取镜像(显示进度),推送到阿里云 ACR
    :param dockerhub_image: Docker Hub 镜像名称(如 `nginx:latest`)
    :param acr_registry: 阿里云 ACR 注册表地址(如 `registry.cn-hangzhou.aliyuncs.com`)
    :param acr_namespace: ACR 命名空间(仓库名称)
    :param acr_username: 阿里云账号或 RAM 用户名
    :param acr_password: 阿里云密码或临时令牌
    """
    # 初始化 Docker 客户端
    client = docker.from_env()

    # 1. 从 Docker Hub 拉取镜像(显示进度)
    print(f"从 Docker Hub 拉取镜像: {dockerhub_image}")
    pull_logs = client.api.pull(
        dockerhub_image,
        stream=True,  # 启用流式输出
        decode=True   # 解析日志为字典
    )

    # 实时显示拉取进度
    for log in pull_logs:
        if "progress" in log:
            print(
                f"层 {log['id']}: {log['status']} "
                f"{log['progress'] if 'progress' in log else ''}"
            )
        else:
            print(f"{log['status']} {log.get('id', '')}".strip())

    # 2. 重命名为阿里云 ACR 格式
    image_with_tag = dockerhub_image.split('/')[-1]
    target_image = f"{acr_registry}/{acr_namespace}/{image_with_tag}"
    alias_image = f"registry-vpc.cn-shenzhen.aliyuncs.com/{acr_namespace}/{image_with_tag}"
    print(f"\n重命名镜像为: {target_image}")
    image = client.images.get(dockerhub_image)
    image.tag(target_image)

    # 3. 登录阿里云 ACR
    print("登录阿里云 ACR...")
    client.login(
        username=acr_username,
        password=acr_password,
        registry=acr_registry
    )

    # 4. 推送镜像到阿里云 ACR
    print(f"推送镜像到阿里云 ACR: {target_image}")
    push_logs = client.images.push(
        target_image,
        stream=True,
        decode=True
    )

    # 显示推送进度(可选)
    for log in push_logs:
        if "error" in log:
            raise Exception(f"推送失败: {log['error']}")
        print(log.get("status", ""), log.get("progress", ""))
    print(f"\n阿里云公网地址为: {target_image}")
    print(f"\n阿里云内网地址为: {alias_image}")
    print("\n操作完成!")

if __name__ == "__main__":
    # 配置参数解析器
    parser = argparse.ArgumentParser(description='从Docker Hub拉取镜像并推送到阿里云ACR')
    parser.add_argument('dockerhub_image', type=str, help='Docker Hub镜像名称(如 nginx:latest)')
    
    # 其他固定参数
    args = parser.parse_args()
    
    # 固定配置的其他参数
    acr_registry = "registry.cn-shenzhen.aliyuncs.com"  # 阿里云 ACR 地址
    acr_namespace = "xxxxx"    # ACR 命名空间(仓库名)
    acr_username = "xxxxxxxxxx"  # 阿里云账号
    acr_password = "xxxxxxxxxx"  # 密码或临时令牌


    # 执行操作
    pull_from_dockerhub_and_push_to_acr(
        args.dockerhub_image,  # 使用命令行参数
        acr_registry,
        acr_namespace,
        acr_username,
        acr_password
    )