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
相关推荐
乘云数字DATABUFF19 小时前
5分钟部署开源APM Databuff:OpenTelemetry全链路追踪入门实战
运维·后端
Patrick_Wilson1 天前
从「改个端口」到 502:Next.js on k8s 的容器端口、Service 映射与 env 覆盖
docker·kubernetes·next.js
Suroy2 天前
DockerView-Go:用 Go 写一个终端 Docker 监控工具,顺便做了个 Web 仪表盘
docker
云恒要逆袭2 天前
运行你的第一个Docker容器
后端·docker·容器
荣--3 天前
一键部署不是为了省时间 —— 它是把"买来的 PaaS"变成"自己的平台"的拐点
运维·zabbix·工程化·一键部署·平台化·边界设计
江华森3 天前
动手实战学 Docker — 从零到集群编排完全指南
运维
宋均浩3 天前
# Docker 镜像瘦身实战:从 1.2G 到 80MB 的五个优化步骤
ci/cd·docker
Avan_菜菜3 天前
FRP 内网穿透完整实战:从 HTTP 映射到 HTTPS 自签代理
运维·nginx·https
程序员老赵3 天前
10 分钟部署 OpenCode:Docker 一键安装,浏览器打开就能用 AI 写代码(附完整命令与排错)
docker·容器·ai编程
WangMingHua1114 天前
LM Studio Docker 部署——本地大模型一键启动
docker