使用 GitHub Actions 自动同步 Docker 镜像到 CNB
版权声明
我们非常重视原创文章,为尊重知识产权并避免潜在的版权问题,我们在此提供文章的摘要供您初步了解。如果您想要查阅更为详尽的内容,访问作者的公众号页面获取完整文章。
为了提升访问速度、增强稳定性并规避部分官方源的不确定性,将常用的开源镜像同步到中国大陆可访问的镜像仓库是一种高效的解决方案。
本文介绍如何通过 GitHub Actions 自动化完成该同步流程,支持选择性构建与定制版本。
背景
许多开源镜像托管在 Docker Hub 上,但由于网络、访问频率限制等问题,拉取速度不稳定,甚至存在连接失败的情况。
之前是使用 GitHub Actions 同步到 CODING 上,不过要 CODING 要停服了,所以改为同步到 CNB 了。
cnb.cool[1] 也是由腾讯出品,基于 Docker 生态,对环境、缓存、插件进行抽象,通过声明式的语法,帮助开发者以更酷的方式构建软件。
支持代码托管、云原生构建和云原生开发等功能。
同步方案概览
镜像列表维护在 .github/images.yml[2] 中; 手动或自动触发 GitHub Actions; 使用 skopeo工具将镜像从 Docker Hub 同步到 CNB;支持选择同步特定镜像或全部镜像; 支持指定版本(tag)。
GitHub Actions 工作流详解
前往 GitHub 查看:docker-proxy.yml[3]
name: MirrorDockerImagestoCNB 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:Mirrorimages 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--argname"$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" exit1 fi echo"$matrix"|whileread-ritem;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" skopeocopy--alldocker://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']
支持两种触发方式:
手动触发:可选择特定镜像名和版本; 自动触发:当 .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。
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 |
|
CNB_DOCKER_TOKEN |
CNB 默认可以创建 npm、Composer 等的制品库,但 Docker 的制品默认就在仓库中,所以创建一个仓库即可。
总结
通过 GitHub Actions + skopeo + CNB 服务,我们构建了一个可复用、自动化、支持多镜像同步的工具链,显著提升了镜像的可用性与部署效率。
cnb.cool: https://cnb.cool/
[2].github/images.yml: https://github.com/sy-records/.github/blob/main/.github/images.yml
[3]docker-proxy.yml: https://github.com/sy-records/.github/blob/main/.github/workflows/docker-proxy.yml
鲁飞
还在用多套工具管项目?
一个平台搞定产品、项目、质量与效能,告别整合之苦,实现全流程闭环。
白皮书上线