大家好,我是飘雷。
只要是玩NAS的兄弟,肯定都绕不开一个让人极其头疼的问题——Docker Hub在国内被大规模阻断,拉取Docker镜像时常常会失败。
谈起这件事,是因为前几天我发布了Easytier异地组网教程后,小黑盒有兄弟在问怎么解决拉取失败的问题。

虽然我自己目前在用比较稳定的付费Docker镜像站,但考虑到有不少兄弟还是倾向于使用免费资源,我就去研究了一下。
现在网上有不少帖子分享了免费的镜像站地址,但问题在于,这些帖子里的链接往往生存周期存疑,可能上个月还能用,现在就失效了。
如果每次拉取镜像时,都要一遍遍去网上找新地址,然后挨个尝试,这会白白浪费大量时间精力,属实是太麻烦了。
那么有没有一劳永逸的办法呢?
有的兄弟,有的。
今天飘雷就给大家分享一款GitHub上的实用开源项目——Docker-Hub-Proxy。
简单来说,它不是自己去给你做一个镜像库,而是一个聪明的Docker镜像站导航与测速工具。
https://github.com/xingfeng7788/docker-hub-proxy
Docker-Hub-Proxy的核心作用有三个:
- 汇总统计全网公开的镜像站资源。
- 自动对这些镜像站进行连通性测速。
- 帮你筛选出延迟最低、当前绝对可用的节点,让你直接复制去拉取镜像。

废话不多说,因为原项目代码有些陈旧,在最新环境部署会报错,所以今天我会手把手教大家如何修改代码,并在NAS上完美部署。
部署流程
这里我们来展示如何在威联通NAS上使用Docker形式部署Docker-Hub-Proxy,用到的设备是威联通最新的8盘位旗舰型号Qu805。

1.下载项目文件
和之前使用Docker Compose代码的常规部署方式不同,这次因为我们需要修改源码,所以首先要前往 GitHub 下载打包后的项目文件 ZIP 压缩包。

解压缩后得到docker-hub-proxy-master文件夹:

2.修改docker-compose.yaml文件
首先使用Notepad++或VS Code之类的代码编辑器,打开文件夹中的docker-compose.yaml文件,根据自己NAS的实际情况,修改为代码中的映射端口号和NAS的实际路径,参考如下:
services:
docker-hub-proxy:
build: .
container_name: docker-hub-proxy
ports:
# 冒号左边修改为未被占用的随意端口号,右侧8000不要变动
- "8765:8000"
volumes:
# 冒号左边修改为你NAS的绝对路径
- /share/Container/dockerhubproxy/data:/app/data
restart: unless-stopped在这段代码中,因为我的Qu805的8000端口号被其他Docker占用了,所以这里我随意将其映射成了8765端口,另外用于保存这个项目数据库的绝对路径设置为/share/Container/dockerhubproxy/data。
3.修改web_ui.py文件
我自己实测,在修改docker-compose.yaml文件,部署后无法正常访问项目的WEB UI管理界面。
猜测可能是因为该项目编写时使用的FastAPI/Starlette库版本较早,现在通过Dockerfile构建时,会自动拉取最新版的库。而在最新版中,TemplateResponse 的调用语法发生了变化,如果不改代码,容器运行后处理网页模板时直接就会崩溃。

这里我们打开docker-hub-proxy-master\app\routers文件夹下的web_ui.py文件,找到第 25 行左右。

修改前的旧代码:
return templates.TemplateResponse("index.html", {
"request": request,
"proxies": [p.model_dump(mode='json') for p in proxies],
"stats": [s.model_dump(mode='json') for s in stats],
"total_download": total_download,
"pull_count": pull_count,
"pull_history": [p.model_dump(mode='json') for p in pull_history]
})我们将其修改为支持新版本库的代码:
return templates.TemplateResponse(
request=request,
name="index.html",
context={
"proxies": [p.model_dump(mode='json') for p in proxies],
"stats": [s.model_dump(mode='json') for s in stats],
"total_download": total_download,
"pull_count": pull_count,
"pull_history": [p.model_dump(mode='json') for p in pull_history]
}
)4.上传并构建部署Docker
将修改好代码的整个文件夹里的文件,全部上传到你的NAS中,比如我就上传到了/share/Container/dockerhubproxy,再在这个文件夹下新建一个data文件夹:

然后开启NAS的SSH功能,使用 Putty 或 FinalShell 登录进NAS后台。


cd进入我们刚才上传的目录:
cd /share/Container/dockerhubproxy
运行构建并启动容器的命令(注意,因为要现场构建镜像,所以必须带上 --build 参数,这个过程可能需要几分钟,请耐心等待):
sudo docker compose up -d --build出现下述字样时,说明项目已经部署成功了:
✔ Network dockerhubproxy_default Created
✔ Container docker-hub-proxy Started
使用方法与配置
1.WEB UI管理设置
部署完成后,在浏览器输入 http://<NAS的IP>:8765(例如 http://192.168.10.70:8765),就能看到 Docker 镜像加速的 UI 界面了。

项目原本设计了搜索Docker 镜像的功能,项目作者给出的效果是这样的:

但不知为何在我这边无法正常工作,不过这并不影响我们拉取镜像的核心需求。
另外,作者原本设计了从特定 URL来自动抓取全网可用的Docker加速节点:
https://status.anye.xyz/status.json但可能因为反爬虫或网站改版,自动抓取功能目前也失效了。
不过这倒是影响不大,我们自己用浏览器打开这个网站,就能看到汇总后的各公共镜像站节点信息:

通过手动添加代理节点的方式同样可以实现汇总,无非就是前期操作稍微麻烦一点儿:

多次添加后,你的列表里就会拥有一个代理池。点击列表上方的「测速」按钮,程序就会自动测试NAS与各个加速节点之间的连通延迟,并且在后续我们使用时,Docker-Hub-Proxy会首选延迟最低的节点链接,为我们实现镜像代理功能。

这里需要提醒大家的是,加速节点延迟低,并不一定代表实际拉取的速度快啊,如果测出来延迟最低的那个站点实际下载很慢,可以把它临时删掉,换延迟第二低的节点测试实际效果。
2.Container Station添加自定义存储库
接下来,我们打开威联通的 Container Station,依次点击左侧的「存储库」 -> 「添加存储库」:
- 提供商:选择「其他」
- 名称:随便起(比如 Local_Turbo)
- URL:填写刚才本机IP+前面我们自定义的端口号(如 http://127.0.0.1:8765)
- 点击应用。

为了验证咱们搭建的加速节点是不是真的好使,咱们直接通过NAS的SSH命令行来一次测试。
如下图所示,在拉取镜像时,我们只需要在原本的镜像名字前面,加上咱们NAS的局域网IP和端口号(例如我的就是 192.168.10.70:8765/),敲下回车后,看到这一排排丝滑的 Pull complete:

然后我们在Container Station中提取映像时,也可以在下拉菜单里选择刚才添加的存储库,同样能够正常拉取:


如果回到WEB UI界面,还可以统计拉取次数、流量历史,以及拉取过的文件等信息:

总结
以上就是本期的全部内容了,感谢大家看到这里。
总的来说,对于被拉取Docker镜像难住,又不想使用付费方案的NAS玩家来说,Docker-Hub-Proxy非常好用,再也不用在各大论坛苦苦求镜像地址了。
只要在后台添加一批公共代理节点,以后咱们拉取镜像时,只需要在镜像名前面加上NAS的局域网IP+端口号就行了,Docker-Hub-Proxy会在后台自动帮我们把请求转发给当前速延迟最低的那个外部节点,实现真正的一劳永逸。
它就像是一个私人定制的镜像站测速探针,虽然不能直接提供代理功能,但能帮我们系统化地管理、筛选网络上那些网络质量良莠不齐的公开镜像站,让我们每次拉取镜像前都能心中有数。
在写作本文过程中,整理代码报错、跑通流程都不易,如果这篇教程对你有所帮助,强烈建议先点个收藏,以防以后需要找可用节点时找不到路,也欢迎大家在评论区互相分享当前还可以使用的节点URL。

