起因
今日购入一台阿里云 ECS,在折腾的时候发现部分国外的镜像拉取速度过慢,并且阿里云 ACR 镜像加速下载的镜像都不是最新的,寻找了些一些解决方案和国内可用的镜像代理服务,在这里做个记录。由于不可抗力,多数镜像代理服务平台已经下线代理,于 2024/10/12 对此文进行更新,下表为收集的加速器列表,不定时更新,有失效可能。目前可用的镜像站已知有企业维护的仅 DaoCloud 镜像站,由于我的机器是阿里云 ECS 因此我使用的阿里云提供的镜像仓库方案,你也可以尝试使用 Cloudflare Wokers 自建镜像加速器。
镜像加速器列表
| 供应商 | 加速器地址 | 备注 | ||
|---|---|---|---|---|
| DaoCloud | https://docker.m.daocloud.io | 仅限境内机器使用,白名单模式,不在名单的镜像需要提交申请。 | ||
| 1plane | https://docker.1panel.live https://dockerproxy.1panel.live https://proxy.1panel.live |
仅限境内机器使用,可能会有流量限制。 |
目前提供镜像加速服务的供应商较少,由于我使用的是阿里云 ECS,因此为了方便,我通过 GitHub Action 定时同步镜像到阿里云 ACR 来使用 Docker,本文的目的就是想跟大家分享一下我在同步镜像的经验,希望可以给大家提供一个参考。
使用 GitHub Action 定时同步镜像到阿里云 ACR
本文主要有以下几个部分:
- 如何在 ACR 中创建镜像仓库命名空间和仓库
- 如何获取 ACR 的授权信息
- 如何配置 GitHub Actions 同步镜像
事不宜迟,那让我们马上开始吧!
Step 1. 在 ACR 中创建镜像仓库命名空间和仓库
搭建第一步是在阿里云容器镜像服务(Aliyun Container Registry)中创建命名空间(namespace)和镜像仓库(repository)。在开始之前,我想先解释一下这个镜像服务地址、命名空间、以及仓库名字的含义。因为明白它们的含义有助于理解下文,理解现在做到哪一步。在下载 Docker image 的时候,一个仓库的全称可能长成下面这样:
registry.cn-shenzhen.aliyuncs.com/qinyangwang/nginx
也就是:
${REGISTRY}/${NAMESPACE}/${REPOSITORY}
具体来说,
REGISTRY 是阿里云容器镜像服务地址,其中的 cn-shenzhen 是区域的地址,你只需要替换到离你最近的区域即可,可用的区域列表请参考地域和可用区列表中的地域ID。
- NAMESPACE 是镜像的命名空间,管理该命名空间下的仓库集合,包括仓库权限和仓库属性,这里你随意设置一个自己记得住的字符串即可。
- REPOSITORY 是镜像仓库的名称,尽量输入易于辨别的字符串,比如我同步 vaultwarden/server 镜像到 ACR 就是 registry.cn-shenzhen.aliyuncs.com/qinyangwang/vaultwarden。
了解了镜像名称之后,我们开始创建镜像仓库实例:
1.登录容器镜像服务控制台。
2.在顶部菜单栏,选择所需地域。

3.在左侧导航栏,选择实例列表。

4.在实例列表页面,单击个人版区域任意位置。

5.在提示对话框单击创建个人版。
6.在个人版实例管理页面选择仓库管理 > 命名空间。

7.在命名空间页面单击创建命名空间。

8.在创建命名空间对话框中设置命名空间名称,单击确定。
Step 2. 获取 ACR 的授权信息
获取镜像仓库的登录名
- 如果您使用的是阿里云账号,阿里云账号就是您的镜像仓库登录名。
- 如果您使用的是 RAM 用户,去掉 RAM 用户账号 aliyundoc.com 后的名称就是您的镜像仓库登录名。例如您的 RAM 用户为 28768383240243****@aliyundoc.com,则您的镜像仓库登录名为28768383240243****。
设置镜像仓库登录密码
1.登录容器镜像服务控制台。
2.单击设置Registry登录密码。

3.在设置Registry登录密码对话框中输入密码和确认密码,单击确定。

Step 3. 配置 GitHub Actions 同步镜像
配置 GitHub Actions 可以参考我的 GitHub 仓库:
1.准备 auth.yaml,images.yaml ,image-sync.yml 这 3 个文件,它们分别是镜像仓库认证信息,源和目标镜像映射关系,Action 工作流模板,按下面的路径存储:
.github/
workflows/
image-sync.yml # Workflow templates
image-sync/
auth.yaml # Docker image repository verification information
images.yaml # Map of source and target images2.除了 image-sync.yml 的路径是固定的,其他两个路径可以自定义,只需要在 image-sync.yml 修改参数即可:
jobs:
sync-images:
with:
auth_file: ./image-sync/auth.yaml # The auth information file of registries, optional.
images_file: ./image-sync/images.yaml # The images file descirbes which images need to sync, always needed.
version: latest # The version of image-syncer, use the latest version if not specified.
proc: 6 # The max number of goroutines to sync images, default value is 5.3.需要在 auth.yaml 中输入目标 registry 的鉴权信息(如果源 registry 也需要鉴权,则源 registry 的鉴权信息也需要输入),最佳实践是将鉴权信息输入到 Secrets 中,然后在 image-sync.yml 中作为 env 使用,最后在 auth.yaml 中以 ${XXX} 的形式引用:
# auth.yaml
registry.cn-hangzhou.aliyuncs.com:
username: ${ACR_USERNAME}
password: ${ACR_PASSWORD}
# image-sync.yml
jobs:
sync-images:
env:
ACR_USERNAME: ${{ secrets.ACR_USERNAME }}
ACR_PASSWORD: ${{ secrets.ACR_PASSWORD }}在 GitHub 仓库的 Settings 中点击 Secrets and variables > Actions,然后在 Repository secrets 点击 New repository secret 来添加鉴权信息:

4.镜像同步配置文件定义了所有的镜像同步规则。每条规则都是一个键值对,键表示“源镜像地址”,值表示“目标镜像地址”。源/目标镜像地址与我们在 docker pull/push 命令中使用的 url 基本相同,但在 “tags” 和 “digest” 部分还是有区别的:
- 源镜像 url 和目标镜像 url 都不能为空。
- 如果源镜像 url 不包含 tags 或 digest,则源仓库的所有 tags 都会被同步。
- 源镜像 url 可以有多个 tags,tags 之间用逗号隔开,只有指定的 tags 才会被同步。
- 源镜像 url 最多只能有一个 digest,目标镜像 url 只能没有 digest 或者同时有相同的 digest。
- 源镜像 url 的“tags”部分可以是一个正则表达式,需要有一个额外的前缀和后缀字符串/。源仓库中所有符合正则表达式的标签都会被同步,不支持多个正则表达式。
- 如果目标镜像 url 没有摘要或标签,则表示源镜像在同步后会保留相同的标签或摘要。
- 目标镜像 url 可以有多个标签,标签数量必须与源镜像url中的标签数量相同,则所有源镜像的标签都会更改为新标签(从左到右对应)。
- “目标镜像 url”也可以是一个数组,每个数组都遵循上述规则。
- 我在
image-sync.yml中配置了两个触发条件,你可以参考 GitHub 文档按需修改:- 每日0点(UTC时间)
- 当
main分支有新的提交
on:
workflow_dispatch:
schedule:
- cron: "0 0 * * *"
push:
branches:
- main
6.配置完成之后,此 Action 会每日定时同步镜像到 ACR 中,我目前使用的镜像较少没有什么特殊的问题,如果你有什么使用问题请在 QinYangWang/actions 这个仓库下提交 issues,我会尽量解答或修复相关问题。