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 反代

使用 1Panel 的还需要将 Nginx 自带配置中的 proxy_set_header Host $host; 注释掉

将下方 add_header www-authenticate 中的域名修改为自己的域名

nginx 复制代码
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 绑定自己的域名

使用方法

单次使用

直接在原拉取命令前添加镜像站地址

sh 复制代码
docker pull mirrors.domain.com/whyour/qinglong:latest

全局使用

通过在配置文件中填写 registry-mirrors 后,你可以直接使用原来的拉取命令来获取镜像

创建 /etc/docker/daemon.json 文件,填入以下内容

json 复制代码
{
  "registry-mirrors": ["https://mirrors.domain.com"]
}

保存后,重启 Docker

sh 复制代码
systemctl daemon-reload
systemctl restart docker

配置 Proxy

如果你没有镜像站,也可以直接配置 Proxy,让 Docker 拉取镜像时走 Proxy 也能够正常使用

创建 /etc/systemd/system/docker.service.d 目录,并在该目录下新建 http-proxy.conf 文件填入以下内容

ini 复制代码
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7890"
Environment="HTTPS_PROXY=http://127.0.0.1:7890"

保存后,重启 Docker

sh 复制代码
systemctl daemon-reload
systemctl restart docker

注意事项

自建的镜像站不要公开使用,Docker Hub 对于拉取频率有限制,对于匿名用户,限制设置为每个 IP 地址每 6 小时 100 次拉取。

通过以下请求获取 Token

sh 复制代码
TOKEN=$(curl "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimitpreview/test:pull" | jq -r .token)

再通过以下请求查看返回的 ratelimit-remaining 值就代表还剩下几次可以拉取

sh 复制代码
curl --head -H "Authorization: Bearer $TOKEN" https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/latest
相关推荐
dntktop2 小时前
内嵌编辑器+AI助手,Wave Terminal打造终端新体验
运维
kaiyuanheshang4 小时前
docker 中的entrypoint和cmd指令
运维·docker·容器·cmd·entrypoint
wanhengwangluo4 小时前
裸金属服务器能够帮助企业解决哪些问题?
运维·服务器
Python私教5 小时前
除了 Docker,还有哪些类似的容器技术?
运维·docker·容器
titxixYY5 小时前
SElinux
linux·运维·服务器
聚名网6 小时前
手机无法连接服务器1302什么意思?
运维·服务器·智能手机
杨浦老苏7 小时前
开源无代码网络数据提取平台Maxun
低代码·docker·群晖
先天打工圣体的男人8 小时前
Linux中安装InfluxDB
linux·运维·服务器
dessler8 小时前
云计算&虚拟化-kvm-克隆(clone)虚拟机
linux·运维·云计算
陌小呆^O^9 小时前
CmakeList.txt之Linux-pthread
linux·运维·服务器