)
为了提升访问速度、增强稳定性并规避部分官方源的不确定性,将常用的开源镜像同步到中国大陆可访问的镜像仓库是一种高效的解决方案。
本文介绍如何通过 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' ]
支持两种触发方式:
- 手动触发:可选择特定镜像名和版本;
- 自动触发:当
.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 |
Docker Hub 登录 token |
CNB_DOCKER_TOKEN |
CNB 镜像仓库推送凭据 |
CNB 默认可以创建 npm、Composer 等的制品库,但 Docker 的制品默认就在仓库中,所以创建一个仓库即可。
总结
通过 GitHub Actions + skopeo + CNB 服务,我们构建了一个可复用、自动化、支持多镜像同步的工具链,显著提升了镜像的可用性与部署效率。
膜拜一下子