自建 Docker Hub 加速镜像:Nginx 反向代理解决方案


自建 Docker Hub 加速镜像:Nginx 反向代理解决方案

前言

随着 Docker Hub 官方源被封锁,国内的镜像源也纷纷下架,现在国内企业和个人服务拉取镜像越来越困难。阿里云、腾讯云等镜像源已经只允许自家服务器使用,其他第三方源也存在稳定性和安全性问题。

所以,自建 Docker Hub 加速镜像就显得很有必要。最常见的做法是:用 Nginx 反向代理 Docker Hub 官方仓库,搭一个属于你自己的"加速入口"。

准备环境

以下是我的环境配置,主打便宜好用,可根据自身情况调整。

  • 系统:Debian / Ubuntu
  • 域名(可选):NameSilo 免备案、价格便宜(.xyz等冷门域名)。没有域名也可以使用自签证书启用 HTTPS

安装 Nginx

1
2
sudo apt update
sudo apt install nginx

开放端口

放行 HTTPS 端口(根据自己服务器情况开放端口,以 ufw 为例):

1
sudo ufw allow 443

配置 Nginx 反代 Docker Hub

创建新配置文件:

1
touch /etc/nginx/conf.d/dockerhub.conf

编辑配置文件:

1
nano /etc/nginx/conf.d/dockerhub.conf

将以下内容粘贴进去,把域名和证书路径改为你自己的,本文示例域名your.domain.com。如果还没证书,可以先用 acme.sh 申请自动证书。

如果用的 NameSilo 的域名,可以参考 acme.sh 的 DNS API 自动申请SSL证书:https://github.com/acmesh-official/acme.sh/wiki/dnsapi#35-use-namesilocom-api

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#反代docker hub镜像源
server {
listen 443 ssl;
server_name your.domain.com;

ssl_certificate /etc/nginx/ssl/your.domain.com.crt;
ssl_certificate_key /etc/nginx/ssl/your.domain.com.key;

ssl_session_timeout 24h;
ssl_protocols TLSv1.2 TLSv1.3;

# /v2/ → https://registry-1.docker.io
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://your.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 认证请求
# 把返回的 `WWW-Authenticate` 头改写为你的入口地址,保证客户端能在你这儿拿到 token。
# /token → https://auth.docker.io
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;
}
}

保存退出(Ctrl+O → 回车 → Ctrl+X)。

重载加载 Nginx 配置

1
sudo nginx -s reload

如果没有报错说明配置生效。

配置 Docker 镜像源

你现在有一个新的私有镜像仓库:https://your.domain.com

接下来让 Docker 走这个仓库,而不是默认的 https://registry-1.docker.io。下面我分几种常见情况讲清楚该怎么做👇

一、临时使用(单次命令)

如果只是想临时从该仓库拉取镜像,例如:

1
docker pull your.domain.com/ubuntu:latest

或者运行:

1
docker run -it your.domain.com/ubuntu bash

这种方式不需要修改配置文件。但要注意:

  • 镜像名前必须加上完整域名(域名
  • 若仓库未使用有效证书(自签名或内部 CA),还需要配置 Docker 信任

二、长期替换默认仓库(推荐)

如果你想让 Docker 默认就从新的仓库拉取镜像,可以通过以下两种方式配置:

方式 1️⃣:修改 /etc/docker/daemon.json

编辑(或新建)文件:

1
sudo nano /etc/docker/daemon.json

加入以下内容(若已有其他字段请合并):

1
2
3
{
"registry-mirrors": ["https://your.domain.com"]
}

然后执行:

1
2
sudo systemctl daemon-reload
sudo systemctl restart docker

验证:

1
docker info | grep -A1 "Registry Mirrors"

输出中应出现:

1
2
Registry Mirrors:
https://your.domain.com/

✅ 说明生效。

方式 2️⃣:使用自定义私有仓库(带认证)

如果你的仓库需要登录(例如 Harbor、Nexus 等),可登录:

1
docker login your.domain.com

然后输入用户名密码。成功后会在 ~/.docker/config.json 中保存凭据。

注意!如果利用反代服务器登录 docker hub 仓库,反代服务器是可以获取到你的账号密码的,所以请谨慎使用他人搭建的服务登录!如果没有拉取自己的私有仓库的镜像的需求,保持匿名拉取相对会安全一些。

三、如果是自签名证书(HTTPS)

若你的 https://your.domain.com 使用自签名证书(非 Let’s Encrypt 等正规证书),Docker 会拒绝连接。

解决方法:

  1. 创建目录:

    1
    sudo mkdir -p /etc/docker/certs.d/your.domain.com
  2. 将证书(例如 ca.crt)复制进去:

    1
    sudo cp ca.crt /etc/docker/certs.d/your.domain.com/
  3. 重启 Docker:

    1
    sudo systemctl restart docker

如果你没有证书,可以临时在 daemon.json 加上:

1
{"insecure-registries": ["your.domain.com"]}

但⚠️这只适合内网或测试环境,生产环境请务必使用 HTTPS 证书。

四、验证是否成功

用的临时方案则执行:

1
docker pull your.domain.com/library/hello-world

用的替换默认仓库方案则执行:

1
docker pull hello-world

拉取成功,你的加速镜像已经生效!

五、安全配置

目前你的 Nginx Docker Hub 镜像是搭建成功了,但默认是公开可访问的,任何人只要知道你的域名,都能用你的服务器中转 Docker Hub。如果被人滥用,会导致:

  • 你的服务器带宽被占满
  • Docker Hub 对你服务器的出口 IP 限速
  • 甚至触发风控或账单暴涨

所以确实需要加一层访问控制,让只有你(或你的机器)能用。很多教程都忽略了这一点。

IP 白名单限制(推荐小团队/个人)

最简单的办法就是IP 白名单限制, 在你的反代配置/etc/nginx/conf.d/dockerhub.conf里,只允许特定 IP 访问 /v2//token

示例:

1
2
3
4
5
6
7
8
9
10
11
12
location /v2/ {
allow 你的本地公网IP; # 比如 allow 123.45.67.89;
allow 你的公司出口IP; # 可写多个 allow
deny all; # 其他一律拒绝
...
}
location /token {
allow 你的本地公网IP;
allow 你的公司出口IP;
deny all;
...
}

✅ 优点:简单高效,无需额外配置
⚠️ 缺点:如果你经常换网络(如笔电或多地服务器),需要手动更新 IP

修改后重新加载 nginx 配置

1
nginx -s reload

好了,完事。


总结

通过本文的详细步骤,您可以成功搭建一个属于自己的 Docker Hub 加速镜像服务。这种方案相比使用公共镜像源有以下优势:

  1. 稳定性:不受公共镜像源服务质量影响
  2. 安全性:可以配置 IP 白名单,限制访问范围
  3. 可控性:完全掌控服务状态和配置
  4. 性能优化:选择距离用户更近的服务器节点

虽然搭建过程相对复杂,但一旦配置完成,就能为您的 Docker 镜像拉取提供稳定可靠的服务保障。


本文转载自技术好学屋,原文地址:自建 Docker Hub 加速镜像(Nginx 反向代理方案)


文章作者: ZeroXin
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 ZeroXin !
  目录