使用 GitHub Actions 自动同步 Docker 镜像到 CNB

为了提升访问速度、增强稳定性并规避部分官方源的不确定性,将常用的开源镜像同步到中国大陆可访问的镜像仓库是一种高效的解决方案。

本文介绍如何通过 GitHub Actions 自动化完成该同步流程,支持选择性构建与定制版本。

背景

许多开源镜像托管在 Docker Hub 上,但由于网络、访问频率限制等问题,拉取速度不稳定,甚至存在连接失败的情况。

之前是使用 GitHub Actions 同步到 CODING 上,不过要 CODING 要停服了,所以改为同步到 CNB 了。

cnb.cool 也是由腾讯出品,基于 Docker 生态,对环境、缓存、插件进行抽象,通过声明式的语法,帮助开发者以更酷的方式构建软件。

支持代码托管、云原生构建和云原生开发等功能。

同步方案概览

  • 镜像列表维护在 .github/images.yml 中;
  • 手动或自动触发 GitHub Actions;
  • 使用 skopeo 工具将镜像从 Docker Hub 同步到 CNB;
  • 支持选择同步特定镜像或全部镜像;
  • 支持指定版本(tag)。

GitHub Actions 工作流详解


点击查看完整文件内容

前往 GitHub 查看:docker-proxy.yml

name: Mirror Docker Images to CNB

on:
  workflow_dispatch:
    inputs:
      name:
        description: 'Select image to mirror (or leave blank to mirror all)'
        required: false
        type: choice
        options:
          - ""
          - vaultwarden
          - bark-server
          - elasticsearch
          - mysql
          - hyperf
          - clickhouse
      version:
        description: 'Override tag version'
        required: false
        type: string
  push:
    paths:
      - '.github/images.yml'
    branches: [ 'main' ]

jobs:
  mirror:
    name: >-
      Mirror ${{ github.event.inputs.name || 'All Images' }}${{ github.event.inputs.version && format(' (version: {0})', github.event.inputs.version) || '' }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Mirror images
        env:
          INPUT_NAME: ${{ github.event.inputs.name }}
          INPUT_VERSION: ${{ github.event.inputs.version }}
        run: |
          images=$(yq -o json '.images' ${{ github.workspace }}/.github/images.yml)

          if [ -n "$INPUT_NAME" ]; then
          matrix=$(echo "$images" | jq -c --arg name "$INPUT_NAME" '.[] | select(.name == $name)')
          else
          matrix=$(echo "$images" | jq -c '.[]')
          fi

          if [ -z "$matrix" ]; then
          echo "No matching images found for name: $INPUT_NAME"
          exit 1
          fi

          echo "$matrix" | while read -r item; do
            image=$(echo "$item" | jq -r '.image')
            name=$(echo "$item" | jq -r '.name')
            default_tag=$(echo "$item" | jq -r '.tag')
            tag=${INPUT_VERSION:-$default_tag}

            echo "Mirroring $image:$tag to docker.cnb.cool/lufei/docker/$name:$tag"

            skopeo copy --all docker://docker.io/${image}:${tag} \
              docker://docker.cnb.cool/lufei/docker/${name}:${tag} \
              --src-creds "${{ secrets.DOCKERHUB_USERNAME }}:${{ secrets.DOCKERHUB_TOKEN }}" \
              --dest-creds "cnb:${{ secrets.CNB_DOCKER_TOKEN }}"

            echo "::notice title=Image Published::https://docker.cnb.cool/lufei/docker/${name}:${tag}"
          done

触发机制

on:
  workflow_dispatch:
    inputs:
      name:     # 可选镜像名
      version:  # 可选覆盖 tag
  push:
    paths:
      - '.github/images.yml'
    branches: [ 'main' ]

支持两种触发方式:

  1. 手动触发:可选择特定镜像名和版本;
  2. 自动触发:当 .github/images.yml 文件变更时,自动同步全量更新。

镜像清单文件

.github/images.yml

images:
  - image: "vaultwarden/server"
    tag: "latest"
    name: "vaultwarden"
  - image: "finab/bark-server"
    tag: "latest"
    name: "bark-server"
  ...

核心同步逻辑

skopeo copy --all docker://docker.io/${image}:${tag} \
  docker://docker.cnb.cool/lufei/docker/${name}:${tag} \
  --src-creds "${{ secrets.DOCKERHUB_USERNAME }}:${{ secrets.DOCKERHUB_TOKEN }}" \
  --dest-creds "cnb:${{ secrets.CNB_DOCKER_TOKEN }}"
  • --all:确保同步多平台镜像(如 amd64 和 arm64);
  • 使用 GitHub Secrets 配置凭据;
  • 输出同步完成后可直接拉取的地址提示。

如何使用

1. 手动触发

在 GitHub → Actions → “Mirror Docker Images to CNB” → 点击 “Run workflow”:

选择镜像

  • 留空镜像名 → 同步所有;
  • 指定镜像名 → 同步该镜像;
  • 同时指定 tag → 覆盖默认 tag。

指定tag

2. 自动触发

每次更新 .github/images.yml 文件并推送到 main 分支时,会自动同步所有的镜像。

镜像拉取示例

同步完成后,用户可直接通过 CNB 公网地址拉取镜像:

docker pull docker.cnb.cool/lufei/docker/hyperf:8.3-alpine-v3.21-swoole

加上https://可以访问网页查看详情:

输出可以访问的镜像链接

安全配置(GitHub Secrets)

名称 用途说明
DOCKERHUB_USERNAME 用于拉取源镜像
DOCKERHUB_TOKEN Docker Hub 登录 token
CNB_DOCKER_TOKEN CNB 镜像仓库推送凭据

CNB 默认可以创建 npm、Composer 等的制品库,但 Docker 的制品默认就在仓库中,所以创建一个仓库即可。

总结

通过 GitHub Actions + skopeo + CNB 服务,我们构建了一个可复用、自动化、支持多镜像同步的工具链,显著提升了镜像的可用性与部署效率。

1 条评论

发表评论

*