一、为什么要自建镜像加速
在国内访问 Docker Hub 拉镜像,慢、超时、限流(匿名拉取有 429 配额)是常态。尤其团队里多台机器反复拉同一个基础镜像,每次都直连 Docker Hub,既慢又费配额。解决办法就是在内网架一台拉取缓存(pull-through cache),第一次回源 Docker Hub 拉取并落盘,之后所有人都是本地秒回。
二、方案选型:registry:2 缓存 vs nginx 反代 vs registry:3
很多人第一反应是用 nginx 反向代理 registry-1.docker.io,但纯反代并不缓存,对"加速"没有任何帮助,甚至多一跳更慢。要实现缓存必须自己叠 nginx proxy_cache,配置复杂且容易踩 Range 请求、摘要校验的坑,不推荐。
真正省心的是用官方 registry 的 pull-through 模式:
- registry:2:经典方案,配置简单,但 GC 要停服,性能一般。
- registry:3:2025 年发布的官方新主线,底层重写,性能更好、在线 GC、配置/存储插件化。新部署直接选 3。
我的结论:registry:3 做缓存 + Nginx 只做 HTTPS 反代/网关,各司其职。
三、整体架构
Podman 客户端 ──https──► registry.ixnic.net (Nginx 443 HTTPS 反代)
│
▼
registry:3 容器 (127.0.0.1:5000)
│ pull-through 缓存, 数据在 /data/registry
▼
Docker Hub (回源)
四、部署 registry:3(Podman 为例)
podman run -d --name registry \ --restart unless-stopped \ -p 5000:5000 \ -e REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io \ -v /data/registry:/var/lib/registry:z \ registry:3
要点:
- REGISTRY_PROXY_REMOTEURL 是 pull-through 的核心配置,指向 Docker Hub。
- 缓存数据在 /data/registry,重建容器不丢缓存。
- 想降日志噪音加 -e REGISTRY_LOG_LEVEL=warn。
- 遇到 429 限流,加 -e REGISTRY_PROXY_USERNAME=xxx -e REGISTRY_PROXY_PASSWORD=xxx(Docker Hub 账号)。
- 如果你更习惯配置文件方式:registry:3 默认读取的路径是 /etc/distribution/config.yml(不是 /etc/registry/config.yml),挂载时务必挂对路径。
五、Nginx 反代配置(AMH 面板为例)
关键三点:关掉 nginx 缓存、透传 Host、透传 Authorization。
server {
listen 443 ssl http2;
server_name registry.ixnic.net;
proxy_cache off; # 缓存交给 registry,nginx 不缓存
proxy_read_timeout 600s; # 大镜像防 504
client_max_body_size 0;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header Authorization $http_authorization; # 必须透传 token
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Accept-Encoding "";
}
}
踩坑记录:
AMH 面板默认会生成 WebSocket 的
Upgrade/Connection头、假Referer、以及proxy_cache缓存配置,这些对 registry 都要去掉——尤其 nginx 缓存会让大 blob 下载损坏。必须开 HTTPS,Docker/Podman 默认拒绝非 HTTPS 的 mirror。
六、客户端配置
Podman(/etc/containers/registries.conf):
[[registry]] prefix = "docker.io" location = "docker.io" [[registry.mirror]] location = "registry.ixnic.net"
Docker(/etc/docker/daemon.json):
{ "registry-mirrors": ["https://registry.ixnic.net"] }
七、验证
# 1. 基础连通(v3 返回 200 是正常行为) curl -sI https://registry.ixnic.net/v2/ | head -5 # 2. 第一次拉(回源,慢)→ 第二次拉(命中缓存,秒回) podman pull docker.io/library/nginx:alpine podman pull docker.io/library/nginx:alpine # 3. 看缓存落盘 sudo du -sh /data/registry
我实测 nginx:alpine 两个大层(29MB/33MB)完整缓存,第二次拉取秒级完成。
八、运维要点
- 缓存无上限增长,需要定期清理;registry:3 支持在线 GC,不用停服。
Registry does not implement RepositoryRemover警告是代理模式正常现象,可忽略。- 日志里每几秒的
GET /(浏览器 UA)通常是监控探活,不影响功能。 - 前提:服务器本身要能顺畅访问 Docker Hub,否则加速效果有限。
九、小结
- 加速选 registry:3 pull-through,nginx 只做反代网关,别用 nginx 缓存。
- 最关键的坑:配置文件路径、Authorization 透传、关 nginx 缓存。
- 一次部署,团队所有 docker/podman 拉取 Docker Hub 镜像秒级完成。
文章末尾固定信息
我的微信
微信号已复制
我的微信
微信扫一扫











