Docker 镜像地址总失效?基于 DockerHub 项目用 GitHub Actions 做一个自动检测状态页

前面我们介绍过这个项目:

text 复制代码
https://github.com/Rodert/DockerHub

它现在主要解决一个非常实际的问题:

Docker Hub 在一些网络环境下不好访问时,到哪里找还能用的镜像地址?

仓库里整理了:

text 复制代码
docker.1panel.live
docker.1ms.run
dockerproxy.net
dockerproxy.link
docker.m.daocloud.io
docker.jiaxin.site

并给出了:

text 复制代码
Windows
macOS
Linux
Rootless Docker

不同环境下的配置方法。

但这种项目维护久了以后,一定会遇到另一个问题:

镜像地址会失效。

今天能用:

text 复制代码
dockerproxy.net

下个月不一定还能用。

某个节点:

text 复制代码
北京访问很快

但:

text 复制代码
广州可能超时。

甚至同一个镜像地址:

text 复制代码
上午正常
下午限流
晚上恢复

所以,如果这个项目只是:

text 复制代码
README 里维护一张静态表格

维护成本会越来越高。

更好的办法是:

让 GitHub Actions 自动测试这些 Docker 镜像地址。

然后生成:

text 复制代码
🟢 可用
🟡 较慢
🔴 不可用

最后自动部署到 GitHub Pages。

这样这个项目就能从:

text 复制代码
Docker 镜像地址收藏夹

升级成:

Docker 镜像实时状态页。

今天我们就从这个思路出发,做一个完整实现。

项目:

text 复制代码
https://github.com/Rodert/DockerHub

一、先看这个项目现在适合怎么扩展

当前仓库本身非常简单。

核心结构可以理解成:

text 复制代码
DockerHub/
├── README.md
├── index.html
├── assets/
└── .github/
    └── workflows/
        └── pages.yml

README.md:

text 复制代码
负责 GitHub 项目介绍。

index.html:

text 复制代码
负责 GitHub Pages 页面。

pages.yml:

text 复制代码
负责自动部署 GitHub Pages。

也就是说:

静态网站基础已经有了。

我们只需要再加一层:

text 复制代码
自动检测。

二、最终架构

我们希望变成:

text 复制代码
mirrors.yml
    ↓
GitHub Actions 定时任务
    ↓
检测每个 Docker Mirror
    ↓
生成 mirrors.json
    ↓
GitHub Pages
    ↓
前端展示状态

最终用户打开网页以后看到:

镜像 状态 延迟 最后检测
docker.1ms.run 🟢 320ms 12:00
dockerproxy.net 🟢 520ms 12:00
dockerproxy.link 🟡 1.8s 12:00
xxx.example.com 🔴 Timeout 12:00

这样比:

text 复制代码
"这里有 6 个地址,你自己试"

体验要好很多。


三、第一步:把镜像地址从 README 拆出来

不要把数据永远写死在:

text 复制代码
README.md

和:

text 复制代码
index.html

里面。

可以创建:

text 复制代码
mirrors.json

最开始:

json 复制代码
[
  {
    "name": "1Panel",
    "url": "docker.1panel.live"
  },
  {
    "name": "1ms",
    "url": "docker.1ms.run"
  },
  {
    "name": "Docker Proxy",
    "url": "dockerproxy.net"
  },
  {
    "name": "Docker Proxy Link",
    "url": "dockerproxy.link"
  },
  {
    "name": "DaoCloud",
    "url": "docker.m.daocloud.io"
  },
  {
    "name": "简行镜像",
    "url": "docker.jiaxin.site"
  }
]

这样以后:

text 复制代码
新增镜像
删除镜像
修改地址

只操作这一个文件。


四、为什么数据和页面一定要分开?

如果地址直接写进:

html 复制代码
<tr>
  <td>docker.1ms.run</td>
</tr>

以后 GitHub Actions 想修改:

text 复制代码
状态
延迟
检测时间

就必须:

text 复制代码
修改 HTML。

非常麻烦。

更合理:

text 复制代码
mirrors.json
=
数据
text 复制代码
index.html
=
展示

这就是最基本的:

数据与视图分离。


五、检测 Docker Mirror,不能只 curl 首页

很多人会写:

bash 复制代码
curl https://docker.1ms.run

返回:

text 复制代码
200

然后认为:

text 复制代码
这个 Docker Mirror 正常。

其实并不可靠。

因为一个 Docker Registry 真正拉镜像需要经过:

text 复制代码
Registry API
Manifest
Blob
Authentication
Redirect

多个环节。

首页能打开:

text 复制代码
≠
镜像能拉。

六、最简单可以检查 Registry V2 API

Docker Registry 有一个非常经典的接口:

text 复制代码
/v2/

比如:

bash 复制代码
curl -I \
  https://docker.1ms.run/v2/

如果 Registry 正常,

可能返回:

text 复制代码
200

或者某些代理:

text 复制代码
401

401 也不一定代表坏了。

反而可能说明:

text 复制代码
Registry 服务本身存在,
只是需要鉴权。

所以检测逻辑不能只写:

bash 复制代码
HTTP != 200
→ Failed

七、更真实一点:检测 nginx Manifest

比如测试:

text 复制代码
library/nginx:latest

我们真正关心:

这个代理能不能访问 Docker Hub 的 nginx Manifest?

可以测试:

text 复制代码
/v2/library/nginx/manifests/latest

例如:

bash 复制代码
curl -L \
  -H 'Accept: application/vnd.docker.distribution.manifest.v2+json' \
  "https://docker.1ms.run/v2/library/nginx/manifests/latest"

不过实际不同 Mirror:

text 复制代码
鉴权
Header
API 转发规则

可能不同。

所以做公共状态检测时,

一个更简单的方法是:

直接使用 Docker CLI。


八、docker manifest inspect 非常适合健康检查

比如:

bash 复制代码
docker manifest inspect \
  docker.1ms.run/library/nginx:latest

如果成功,

说明至少:

text 复制代码
Registry 可访问
nginx Repository 可访问
Manifest 可获取

而且:

text 复制代码
不需要真正下载所有 Layer。

这比:

bash 复制代码
docker pull nginx

轻量很多。


九、写一个检测脚本

创建:

text 复制代码
scripts/check-mirrors.py

例如:

python 复制代码
import json
import subprocess
import time
from datetime import datetime, timezone


MIRRORS_FILE = "mirrors.json"
OUTPUT_FILE = "mirror-status.json"


def check_mirror(url: str):
    image = f"{url}/library/nginx:latest"

    start = time.time()

    try:
        result = subprocess.run(
            [
                "docker",
                "manifest",
                "inspect",
                image,
            ],
            stdout=subprocess.DEVNULL,
            stderr=subprocess.PIPE,
            timeout=20,
        )

        elapsed = int(
            (time.time() - start) * 1000
        )

        if result.returncode == 0:
            return {
                "status": "online",
                "latency": elapsed,
                "error": None,
            }

        return {
            "status": "offline",
            "latency": elapsed,
            "error": (
                result.stderr
                .decode(
                    "utf-8",
                    errors="ignore"
                )
                [:300]
            ),
        }

    except subprocess.TimeoutExpired:
        return {
            "status": "timeout",
            "latency": None,
            "error": "timeout",
        }


def main():
    with open(
        MIRRORS_FILE,
        "r",
        encoding="utf-8",
    ) as f:

        mirrors = json.load(f)

    results = []

    for mirror in mirrors:

        print(
            "Checking:",
            mirror["url"]
        )

        result = check_mirror(
            mirror["url"]
        )

        results.append({
            **mirror,
            **result,
            "checked_at": (
                datetime
                .now(timezone.utc)
                .isoformat()
            ),
        })

    with open(
        OUTPUT_FILE,
        "w",
        encoding="utf-8",
    ) as f:

        json.dump(
            results,
            f,
            ensure_ascii=False,
            indent=2,
        )


if __name__ == "__main__":
    main()

执行:

bash 复制代码
python scripts/check-mirrors.py

十、最后生成什么?

例如:

json 复制代码
[
  {
    "name": "1ms",
    "url": "docker.1ms.run",
    "status": "online",
    "latency": 416,
    "error": null,
    "checked_at": "2026-10-05T03:20:00+00:00"
  },
  {
    "name": "Docker Proxy",
    "url": "dockerproxy.net",
    "status": "timeout",
    "latency": null,
    "error": "timeout",
    "checked_at": "2026-10-05T03:20:21+00:00"
  }
]

这份:

text 复制代码
mirror-status.json

就可以直接给前端读取。


十一、状态不能只有 online / offline

实际镜像服务还有一种:

text 复制代码
能用,
但是特别慢。

比如:

text 复制代码
300ms

和:

text 复制代码
8 秒

虽然都:

text 复制代码
成功。

体验完全不同。

所以可以定义:

python 复制代码
def classify(
    success: bool,
    latency: int | None
):
    if not success:
        return "offline"

    if latency is None:
        return "offline"

    if latency < 1000:
        return "fast"

    if latency < 3000:
        return "slow"

    return "very_slow"

页面:

text 复制代码
🟢 < 1 秒

🟡 1~3 秒

🟠 > 3 秒

🔴 不可用

用户一眼就能看懂。


十二、但是一次测试不够可靠

比如:

text 复制代码
dockerproxy.net

刚好:

text 复制代码
12:00

有一次网络抖动。

如果只测试一次:

text 复制代码
Timeout

页面就直接显示:

text 复制代码
🔴 Offline

其实可能是误判。

更加可靠:

连续检测 3 次。


十三、例如写一个 retry

python 复制代码
def check_with_retry(
    url,
    retries=3
):

    results = []

    for _ in range(retries):

        result = check_mirror(
            url
        )

        results.append(
            result
        )

        if (
            result["status"]
            == "online"
        ):
            break

        time.sleep(2)

    return results

如果:

text 复制代码
3 次全部失败

再标:

text 复制代码
offline。

如果:

text 复制代码
第 1 次失败
第 2 次成功

可以:

text 复制代码
unstable

标黄。

这比:

text 复制代码
一次请求定生死

靠谱很多。


十四、甚至可以计算成功率

比如每 6 小时检测一次。

一天:

text 复制代码
4 次。

七天:

text 复制代码
28 次。

镜像 A:

text 复制代码
成功 27 次。

可用率:

text 复制代码
96.4%

镜像 B:

text 复制代码
成功 18 次。

可用率:

text 复制代码
64.3%

这个指标比:

text 复制代码
"现在能不能用"

更有价值。

因为用户真正关心:

稳不稳定。


十五、可以记录历史

例如:

text 复制代码
history/
├── 2026-10-01.json
├── 2026-10-02.json
├── 2026-10-03.json
└── 2026-10-04.json

或者:

json 复制代码
{
  "docker.1ms.run": [
    {
      "time": "...",
      "latency": 320,
      "status": "online"
    },
    {
      "time": "...",
      "latency": 480,
      "status": "online"
    }
  ]
}

这样以后甚至可以画:

延迟趋势图。


十六、下一步:GitHub Actions 自动跑

这才是关键。

创建:

text 复制代码
.github/workflows/check-mirrors.yml

内容:

yaml 复制代码
name: Check Docker Mirrors

on:

  schedule:
    - cron: "0 */6 * * *"

  workflow_dispatch:

jobs:

  check:

    runs-on: ubuntu-latest

    permissions:
      contents: write

    steps:

      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.12"

      - name: Check mirrors
        run: |
          python scripts/check-mirrors.py

      - name: Commit result
        run: |
          git config user.name \
            "github-actions[bot]"

          git config user.email \
            "41898282+github-actions[bot]@users.noreply.github.com"

          git add mirror-status.json

          git diff --cached --quiet && exit 0

          git commit -m \
            "chore: update mirror status"

          git push

现在:

每 6 小时自动检测一次。


十七、cron 怎么看?

yaml 复制代码
cron: "0 */6 * * *"

意思:

text 复制代码
每 6 小时一次。

例如:

text 复制代码
00:00
06:00
12:00
18:00

GitHub Actions 的 Schedule 时间:

text 复制代码
通常按 UTC 理解。

如果你特别在意北京时间,

需要换算。


十八、为什么还要 workflow_dispatch?

这一段:

yaml 复制代码
workflow_dispatch:

表示:

可以手动执行。

比如你刚收到 Issue:

dockerproxy.net 挂了。

不用等:

text 复制代码
下一次定时任务。

GitHub:

text 复制代码
Actions
↓
Check Docker Mirrors
↓
Run workflow

马上检测。

特别适合维护这种资源库。


十九、然后 GitHub Pages 怎么更新?

项目本身已经有:

text 复制代码
pages.yml

用于:

text 复制代码
main push
↓
自动部署 Pages。

所以检测 Workflow:

text 复制代码
检测完成
↓
更新 mirror-status.json
↓
commit
↓
push main

会进一步触发:

text 复制代码
Pages Workflow

然后:

text 复制代码
自动部署网站。

整个链路:

text 复制代码
定时任务
↓
检查 Docker Mirror
↓
生成 JSON
↓
Commit
↓
Push
↓
GitHub Pages Deploy
↓
用户看到最新状态

完全自动。


二十、这就是 GitHub Actions 很适合做的事情

不需要:

text 复制代码
服务器
数据库
定时任务服务器

只需要:

text 复制代码
GitHub Repo。

就能完成:

text 复制代码
定时检测
数据生成
网页发布

成本非常低。


二十一、前端怎么读取状态?

现在:

text 复制代码
index.html

可以不再写死表格。

增加:

html 复制代码
<tbody id="mirror-list"></tbody>

然后 JavaScript:

html 复制代码
<script>
async function loadMirrors() {

    const response =
        await fetch(
            "./mirror-status.json"
        );

    const mirrors =
        await response.json();

    const tbody =
        document.getElementById(
            "mirror-list"
        );

    for (
        const mirror
        of mirrors
    ) {

        const tr =
            document.createElement(
                "tr"
            );

        tr.innerHTML = `
            <td>
                ${mirror.name}
            </td>

            <td>
                <code>
                    ${mirror.url}
                </code>
            </td>

            <td>
                ${renderStatus(
                    mirror.status
                )}
            </td>

            <td>
                ${
                    mirror.latency
                    ? mirror.latency + " ms"
                    : "-"
                }
            </td>
        `;

        tbody.appendChild(
            tr
        );
    }
}

loadMirrors();
</script>

这样表格自动生成。


二十二、状态可以做得更直观

例如:

javascript 复制代码
function renderStatus(
    status
) {

    switch (status) {

        case "online":
            return "🟢 可用";

        case "slow":
            return "🟡 较慢";

        case "timeout":
            return "🟠 超时";

        default:
            return "🔴 不可用";
    }
}

页面立刻变成:

text 复制代码
DockerHub 镜像集中营

1ms
🟢 可用
420ms

DockerProxy
🟡 较慢
1870ms

DaoCloud
🔴 不可用
-

比纯文本列表好很多。


二十三、再加一个"一键复制地址"

例如:

html 复制代码
<button
  onclick="
    navigator.clipboard.writeText(
      'https://docker.1ms.run'
    )
  "
>
  复制
</button>

用户:

text 复制代码
点击
↓
复制
↓
粘贴 daemon.json

不用自己拖选。

这类小细节对工具站很重要。


二十四、甚至可以自动生成 daemon.json

页面上放:

text 复制代码
☑ 1ms

☑ DockerProxy

☑ DaoCloud

用户选中:

text 复制代码
1ms
DockerProxy

页面实时生成:

json 复制代码
{
  "registry-mirrors": [
    "https://docker.1ms.run",
    "https://dockerproxy.net"
  ]
}

点击:

text 复制代码
复制配置。

这个功能非常适合小白。


二十五、可以加操作系统 Tabs

比如:

text 复制代码
Windows
macOS
Linux
Rootless

用户点 Linux:

显示:

bash 复制代码
sudo mkdir -p /etc/docker
sudo vim /etc/docker/daemon.json
sudo systemctl restart docker

点 macOS:

显示:

text 复制代码
Docker Desktop
→ Settings
→ Docker Engine
→ Apply & Restart

这样这个站就不只是:

text 复制代码
地址列表。

而是:

Docker 镜像配置工具。


二十六、甚至可以自动生成直接 pull 命令

用户选择:

text 复制代码
Mirror:
docker.1ms.run

输入:

text 复制代码
nginx:latest

自动生成:

bash 复制代码
docker pull \
  docker.1ms.run/library/nginx:latest

如果输入:

text 复制代码
username/myapp:v1

生成:

bash 复制代码
docker pull \
  docker.1ms.run/username/myapp:v1

注意这里就需要处理:

library Namespace。


二十七、可以写一个简单转换函数

javascript 复制代码
function buildProxyImage(
    mirror,
    image
) {

    if (
        image.includes("/")
    ) {
        return (
            mirror
            + "/"
            + image
        );
    }

    return (
        mirror
        + "/library/"
        + image
    );
}

例如:

javascript 复制代码
buildProxyImage(
    "docker.1ms.run",
    "nginx:latest"
)

返回:

text 复制代码
docker.1ms.run/library/nginx:latest

输入:

text 复制代码
rodert/myapp:v1

返回:

text 复制代码
docker.1ms.run/rodert/myapp:v1

这对小白特别实用。


二十八、还可以加 Docker Compose 转换

用户粘贴:

yaml 复制代码
services:

  nginx:
    image: nginx:latest

  redis:
    image: redis:7

  mysql:
    image: mysql:8.4

工具自动转换:

yaml 复制代码
services:

  nginx:
    image:
      docker.1ms.run/library/nginx:latest

  redis:
    image:
      docker.1ms.run/library/redis:7

  mysql:
    image:
      docker.1ms.run/library/mysql:8.4

虽然生产上我更倾向:

text 复制代码
配置 registry-mirrors

而不是修改所有 Compose,

但临时环境非常方便。


二十九、Dockerfile 也可以做类似处理

例如:

Dockerfile 复制代码
FROM golang:1.25 AS builder

FROM alpine:latest

转换:

Dockerfile 复制代码
FROM docker.1ms.run/library/golang:1.25 AS builder

FROM docker.1ms.run/library/alpine:latest

这样在:

text 复制代码
无法修改 Docker Daemon

的环境里,也能直接使用代理。


三十、这就从"镜像列表"升级成开发者工具站了

整个产品路线:

text 复制代码
V1
镜像地址列表

↓

text 复制代码
V2
自动可用性检测

↓

text 复制代码
V3
延迟和历史稳定性

↓

text 复制代码
V4
自动生成 daemon.json

↓

text 复制代码
V5
Docker Pull 命令生成

↓

text 复制代码
V6
Compose / Dockerfile 转换

一个很小的 GitHub 仓库,

完全可以逐步变成:

Docker 国内使用工具箱。


三十一、再说自动检测最容易踩的一个坑

GitHub Actions 的服务器:

text 复制代码
不在国内。

这意味着:

text 复制代码
GitHub Actions 测出来可用

不代表:

text 复制代码
中国大陆用户一定可用。

这是这个方案最大的限制之一。


三十二、为什么?

因为:

text 复制代码
GitHub Actions Runner

可能从海外网络访问:

text 复制代码
docker.1ms.run

速度:

text 复制代码
100ms。

而国内用户:

text 复制代码
可能 2 秒。

甚至反过来。

所以:

GitHub Actions 状态只能代表一个检测节点。

不能代表所有地区。


三十三、怎么解决?

可以增加:

Community Report。

例如每个 Mirror 页面允许用户反馈:

text 复制代码
北京 🟢

上海 🟢

广东 🔴

四川 🟡

或者通过 GitHub Issues:

text 复制代码
镜像失效反馈。

自动形成:

text 复制代码
机器检测
+
用户反馈

两套信号。

这样准确性更高。


三十四、更进一步可以有国内检测节点

如果以后愿意投入一点服务器资源,

可以准备:

text 复制代码
北京 VPS
上海 VPS
广州 VPS

分别:

text 复制代码
Cron
↓
检测 Mirrors
↓
提交结果 API

得到:

text 复制代码
多地区状态。

最终:

Mirror 北京 上海 广州
1ms 🟢 120ms 🟢 95ms 🟡 1.2s
Proxy 🟡 1.5s 🟢 320ms 🔴

这就非常有价值了。


三十五、还可以计算综合评分

比如:

text 复制代码
Availability:
60%

Latency:
25%

Recent Stability:
15%

最终:

text 复制代码
Score = 92

镜像排序:

text 复制代码
1. 1ms        92
2. DaoCloud   86
3. Proxy      74

用户直接:

选第一名。

而不是自己一个个试。


三十六、一个简单评分算法

例如:

python 复制代码
def mirror_score(
    uptime,
    latency
):
    uptime_score = (
        uptime * 0.7
    )

    if latency < 500:
        latency_score = 30

    elif latency < 1000:
        latency_score = 25

    elif latency < 3000:
        latency_score = 15

    else:
        latency_score = 5

    return (
        uptime_score
        +
        latency_score
    )

例如:

text 复制代码
可用率 95%
延迟 400ms

得分:

text 复制代码
95 × 0.7
+
30
=
96.5

当然真实算法可以继续优化。


三十七、另外一个有意思的功能:检测具体热门镜像

只测:

text 复制代码
nginx

可能不够。

可以选择:

text 复制代码
nginx
redis
mysql
ubuntu
node
golang

例如:

python 复制代码
IMAGES = [
    "library/nginx:latest",
    "library/redis:7",
    "library/mysql:8.4",
    "library/ubuntu:24.04",
]

一个 Mirror:

text 复制代码
4 个都通过

才:

text 复制代码
🟢。

如果:

text 复制代码
nginx OK
mysql Fail

可以标:

text 复制代码
🟡 部分可用。

三十八、为什么可能出现部分可用?

不同代理:

text 复制代码
缓存策略
Repository 支持
上游限制

可能不同。

所以:

text 复制代码
能拉 nginx

并不绝对意味着:

text 复制代码
任何 Docker Hub Image 都能拉。

多镜像检测会更真实。


三十九、还可以检测架构 Manifest

现在很多开发者:

text 复制代码
Intel Linux
Apple Silicon
ARM Server

都在用 Docker。

镜像可能包含:

text 复制代码
linux/amd64
linux/arm64

如果 Mirror Manifest 处理有问题,

可能导致:

text 复制代码
Mac M 系列

用户失败。

所以可以检测:

bash 复制代码
docker manifest inspect nginx:latest

并检查:

text 复制代码
amd64
arm64

是否都存在。

这又多了一层:

Multi-Arch 健康检查。


四十、项目为什么适合开源共建?

因为这类资源:

text 复制代码
变化非常快。

单个人永远不可能:

text 复制代码
全天候盯着 20 个镜像。

但 GitHub 很适合:

text 复制代码
Issues
Pull Requests
Actions
Pages

组合。

用户发现:

text 复制代码
某地址失效。

提交 Issue。

有人发现:

text 复制代码
新 Mirror。

提交 PR。

Action:

text 复制代码
自动测试。

通过:

text 复制代码
再 Merge。

这就形成:

社区维护闭环。


四十一、甚至可以给 PR 自动做可用性测试

假设有人 PR:

json 复制代码
{
  "name": "New Mirror",
  "url": "mirror.example.com"
}

GitHub Action 自动:

text 复制代码
读取新增地址
↓
docker manifest inspect
↓
测试 nginx
↓
测试 redis
↓
成功

PR 上显示:

text 复制代码
✅ Mirror Check Passed

失败:

text 复制代码
❌ Mirror Check Failed

这样维护者:

不需要手工测试每一个 PR。


四十二、这就是 CI 的另一个用途

很多程序员理解 GitHub Actions:

text 复制代码
编译代码
跑单元测试。

其实它更本质的能力是:

自动执行重复任务。

所以:

text 复制代码
API 健康检查

链接检测

镜像检测

数据抓取

README 生成

Pages 部署

都可以做。


四十三、项目甚至可以自动更新 README

比如状态检测完成以后,

自动把:

markdown 复制代码
| 服务 | 地址 | 状态 |
|---|---|---|

生成出来。

Python:

python 复制代码
def markdown_table(
    mirrors
):

    lines = [
        "| 服务 | 地址 | 状态 |",
        "| --- | --- | --- |",
    ]

    for m in mirrors:

        if m["status"] == "online":
            status = "🟢 可用"

        else:
            status = "🔴 不可用"

        lines.append(
            f"| {m['name']} "
            f"| `{m['url']}` "
            f"| {status} |"
        )

    return "\n".join(
        lines
    )

然后自动写入:

text 复制代码
README.md

这样:

GitHub README 和 Pages 状态永远同步。


四十四、不过我更建议 README 保持稳定

不要每 6 小时:

text 复制代码
自动 Commit README。

否则 Git History 会被:

text 复制代码
状态更新 Commit

刷满。

更合理:

text 复制代码
README
=
长期说明
text 复制代码
mirror-status.json
=
动态状态

Pages 读取 JSON。

GitHub 首页:

text 复制代码
只展示链接到状态页。

这样仓库更干净。


四十五、如果不想产生大量 Commit 呢?

甚至可以:

text 复制代码
GitHub Actions
↓
生成静态站点 artifact
↓
直接部署 Pages

不把:

text 复制代码
mirror-status.json

提交回 main。

流程:

text 复制代码
Checkout
↓
Check Mirrors
↓
生成 JSON
↓
Upload Pages Artifact
↓
Deploy

这样:

text 复制代码
Git History

完全不会因为状态检测变脏。

这是更优雅的设计。


四十六、例如一个合并后的 Workflow

yaml 复制代码
name: Check Mirrors and Deploy

on:

  schedule:
    - cron: "0 */6 * * *"

  push:
    branches:
      - main

  workflow_dispatch:

permissions:

  contents: read

  pages: write

  id-token: write

jobs:

  deploy:

    runs-on: ubuntu-latest

    environment:
      name: github-pages

    steps:

      - uses:
          actions/checkout@v4

      - uses:
          actions/setup-python@v5
        with:
          python-version: "3.12"

      - name: Check mirrors
        run: |
          python scripts/check-mirrors.py

      - name: Configure Pages
        uses:
          actions/configure-pages@v5

      - name: Upload Pages
        uses:
          actions/upload-pages-artifact@v3
        with:
          path: .

      - name: Deploy
        uses:
          actions/deploy-pages@v4

现在:

text 复制代码
每 6 小时

整个网站:

text 复制代码
重新检测
+
重新部署。

而仓库:

text 复制代码
没有新的状态 Commit。

四十七、我认为这是这个项目最值得做的下一版

当前:

text 复制代码
DockerHub 镜像集中营

解决:

"有哪些地址?"

下一步应该解决:

"现在到底哪个最好用?"

这是两个完全不同的价值。

第一层:

text 复制代码
Information Collection

第二层:

text 复制代码
Decision Support。

后者对用户价值明显更高。


四十八、再往后甚至可以做自动推荐

用户打开网页。

系统直接显示:

text 复制代码
今日推荐:

🥇 docker.1ms.run

过去 7 天可用率:
99.2%

当前延迟:
286ms

支持:
nginx / redis / mysql / node

然后一个按钮:

text 复制代码
复制 Docker 配置

用户:

text 复制代码
10 秒

解决 Docker 拉取问题。

这才是真正优秀的工具体验。


四十九、项目还可以加入"一键诊断"

用户运行:

bash 复制代码
curl -fsSL \
  https://xxx/diagnose.sh \
  | bash

脚本输出:

text 复制代码
[1] Docker Version
Docker 28.x

[2] Daemon
OK

[3] Registry Mirrors
docker.1ms.run

[4] Docker Hub
Timeout

[5] Mirror
1ms OK 320ms

建议:
当前 Docker Hub 直连异常,
建议使用 docker.1ms.run。

当然公开脚本执行时需要非常注意:

text 复制代码
透明
安全
可审计

最好用户先查看:

text 复制代码
脚本内容。

五十、一个更简单安全的 diagnose.sh

例如:

bash 复制代码
#!/usr/bin/env bash


echo "=== Docker Version ==="

docker version \
  --format \
  '{{.Server.Version}}'


echo

echo "=== Registry Mirrors ==="

docker info \
  --format \
  '{{json .RegistryConfig.Mirrors}}'


echo

echo "=== Pull Test ==="

timeout 30 \
  docker pull \
  hello-world:latest

至少可以快速发现:

text 复制代码
Docker 是否启动

Mirror 是否加载

Pull 是否正常

五十一、这个项目实际上很适合新手学习 GitHub Actions

因为业务非常简单:

text 复制代码
输入:
一批 URL
text 复制代码
处理:
检测
text 复制代码
输出:
JSON
text 复制代码
展示:
HTML

然后:

text 复制代码
自动化:
GitHub Actions

整个流程涉及:

text 复制代码
Python
Docker
HTTP
JSON
GitHub Actions
GitHub Pages

但又不复杂。

非常适合作为:

自动化入门项目。


五十二、而且非常适合再接 AI

比如以后:

text 复制代码
用户提交 Issue:
"广州电信 dockerproxy.net 最近很慢"

AI Agent 可以自动:

text 复制代码
读取 Issue
↓
判断对应 Mirror
↓
触发检测
↓
分析过去 7 天数据
↓
生成报告

再自动回复:

text 复制代码
最近 24 小时成功率 62%,
平均延迟 3.2 秒,
已暂时标记为不推荐。

这就是:

AI + DevOps Automation。


五十三、甚至可以让 AI 自动维护 README

比如新增镜像:

text 复制代码
mirror.example.com

Agent:

text 复制代码
1. 检查 Registry

2. 检查 nginx Manifest

3. 检查 redis Manifest

4. 检查是否需要登录

5. 检查是否属于付费服务

6. 生成 README 条目

7. 创建 PR

人工只需要:

text 复制代码
Review。

这会让项目维护成本进一步下降。


总结

Rodert/DockerHub 当前已经解决了一个很实用的问题:

text 复制代码
Docker 镜像地址不好找
↓
集中整理。

但这类项目最大的敌人不是:

text 复制代码
代码 Bug。

而是:

信息过期。

因为公共 Docker 镜像:

text 复制代码
会失效
会限流
会变慢
会更换域名

所以这类项目最理想的下一步,不是:

text 复制代码
人工继续往 README 填更多地址。

而是:

text 复制代码
镜像地址列表
↓
GitHub Actions
↓
自动健康检查
↓
Manifest 验证
↓
延迟统计
↓
可用率统计
↓
GitHub Pages
↓
实时状态页面

再进一步:

text 复制代码
自动推荐最佳 Mirror
↓
一键生成 daemon.json
↓
一键生成 docker pull
↓
Compose / Dockerfile 转换

这样:

text 复制代码
DockerHub 镜像集中营

就会从:

"一个 Docker 镜像地址收藏仓库"

慢慢变成:

"一个真正能帮助开发者判断、配置和排查 Docker 镜像问题的工具站"。

如果只记住一句话:

持续变化的数据,不应该只靠人肉维护 README;最适合的方式,是把检测、更新和发布全部自动化。

项目地址:

text 复制代码
https://github.com/Rodert/DockerHub
相关推荐
天衍四九-1 小时前
Docker 进阶实战系列(一):容器镜像安全,最小镜像与非 Root 运行
安全·docker·eureka
miofly1 小时前
GitHub 日榜趋势速报 | 2026-10-06
开源·github
天衍四九-1 小时前
Docker进阶实战系列(二):容器日志深度治理|驱动配置、自动切割、磁盘爆满彻底解决
docker·容器·eureka
sbjdhjd2 小时前
云安全 | Docker 容器逃逸复盘(一):从隔离边界到运行时链路,如何确认自己身处容器
网络安全·docker·云原生·容器·kubernetes·云计算·云安全
溪语流沙2 小时前
【Web全栈进阶】PostgreSQL上手:Docker跑库 + 把早报站从SQLite迁过去
前端·docker·postgresql
梦想不只是梦与想12 小时前
docker-compose.yml
docker·docker-compose·docker run
ianzh17 小时前
workbuddy-to-dsh使用教程
github
YahirQ17 小时前
技术博客一键多发实战:基于 GitHub Actions 与双引擎的自动化发布流水线
github
恒拓高科WorkPlus19 小时前
企业怎样选择IM即时通讯平台?私有化部署还是SaaS更适合?
网络·github