Docker 镜像拉不动?自建 Docker Hub 加速站 解决镜像拉取失败
前言
众所周知,6 月份的时候,Docker Hub 的镜像就已经无法正常拉取,那会随手用 Nginx 反代了一下 Docker Hub,建了个自用的镜像站,一直用到了 9 月份,发现自建的镜像站也无法正常的拉取镜像了,看 Nginx 的日志全是 401 错误。
而拉取时候的报错则是连接不到 auth.docker.io
,没想到是认证的域名也访问不到了,所以自己反代的镜像站也就无法拉取了。
于是在这里总结一下国内可以正常拉取镜像的方法,一种方法行不通了可以其他方法接着用
- 通过 Nginx 反代 Docker Hub,现在还需要同时反代
auth.docker.io
- 通过 Cloudflare Workers 反代
- Docker 配置 Proxy
Nginx 反代
TIP
使用 1Panel 的还需要将 Nginx 自带配置中的 proxy_set_header Host $host;
注释掉
将下方 add_header www-authenticate
中的域名修改为自己的域名
location /v2/ {
proxy_pass https://registry-1.docker.io; # Docker Hub 的官方镜像仓库
proxy_set_header Host registry-1.docker.io;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 关闭缓存
proxy_buffering off;
# 转发认证相关的头部
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
# 重写 www-authenticate 头为你的反代地址
proxy_hide_header www-authenticate;
add_header www-authenticate 'Bearer realm="https://mirrors.domain.com/token",service="registry.docker.io"' always;
# always 参数确保该头部在返回 401 错误时无论什么情况下都会被添加。
# 对 upstream 状态码检查,实现 error_page 错误重定向
proxy_intercept_errors on;
# error_page 指令默认只检查了第一次后端返回的状态码,开启后可以跟随多次重定向。
recursive_error_pages on;
# 根据状态码执行对应操作,以下为301、302、307状态码都会触发
error_page 301 302 307 = @handle_redirect;
}
# 处理 Docker OAuth2 Token 认证请求
location /token {
resolver 1.1.1.1 valid=600s;
proxy_pass https://auth.docker.io; # Docker 认证服务器
# 设置请求头,确保转发正确
proxy_set_header Host auth.docker.io;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 传递 Authorization 头信息,获取 Token
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
# 禁用缓存
proxy_buffering off;
}
location @handle_redirect {
resolver 1.1.1.1;
set $saved_redirect_location '$upstream_http_location';
proxy_pass $saved_redirect_location;
}
Workers 反代
如果你没有自己的 VPS,那么可以使用 Cloudflare 提供的 Workers 进行反代,但需要注意的,反代可能会违反 Cloudflare 的 ToS 导致账号违规
点击左侧的 Worker & Pages,然后点击 Create Worker 来新建一个 Worker
名字可以随意命名,可以直接点击右下角的 Deploy 进行部署
然后编辑代码,将自带的内容全部删除后,复制 Github 的 _worker.js 中的代码并将 workers_url
修改为自己的绑定的域名
由于自带的 workers.dev 域名无法正常访问,还需要在 Settings -> Domains & Routes 绑定自己的域名
使用方法
单次使用
直接在原拉取命令前添加镜像站地址
docker pull mirrors.domain.com/whyour/qinglong:latest
全局使用
通过在配置文件中填写 registry-mirrors
后,你可以直接使用原来的拉取命令来获取镜像
创建 /etc/docker/daemon.json
文件,填入以下内容
{
"registry-mirrors": ["https://mirrors.domain.com"]
}
保存后,重启 Docker
systemctl daemon-reload
systemctl restart docker
配置 Proxy
如果你没有镜像站,也可以直接配置 Proxy,让 Docker 拉取镜像时走 Proxy 也能够正常使用
创建 /etc/systemd/system/docker.service.d
目录,并在该目录下新建 http-proxy.conf
文件填入以下内容
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7890"
Environment="HTTPS_PROXY=http://127.0.0.1:7890"
保存后,重启 Docker
systemctl daemon-reload
systemctl restart docker
注意事项
自建的镜像站不要公开使用,Docker Hub 对于拉取频率有限制,对于匿名用户,限制设置为每个 IP 地址每 6 小时 100 次拉取。
通过以下请求获取 Token
TOKEN=$(curl "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimitpreview/test:pull" | jq -r .token)
再通过以下请求查看返回的 ratelimit-remaining
值就代表还剩下几次可以拉取
curl --head -H "Authorization: Bearer $TOKEN" https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/latest
预览: