环境说明
client -- > nginx(192.168.74.100) --> docker hub
确认 docker hub 认证信息
curl -v https://xxxx/v2/
......
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x55a26fae0670)
> GET /v2/ HTTP/2
> Host: xxxxx
> user-agent: curl/7.71.1
> accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
< HTTP/2 401
< content-type: application/json;charset=utf-8
< date: Fri, 11 Sep 2026 09:45:41 GMT
< www-authenticate: Bearer realm="https://xxxxxx/v2/auth",service="bkrepo",scope="repository:*/*/tb:push,pull"
< content-length: 284
<
{
"errors" : [ {
"message" : "authentication required",
"code" : "UNAUTHORIZED",
"detail" : "The access controller was unable to authenticate the client. Often this will be accompanied by a Www-Authenticate HTTP response header indicating how to authenticate."
} ]
}
* Connection #0 to host xxxxx left intact
关注这行信息,nginx 配置会用到
www-authenticate: Bearer realm="https://xxxxxx/v2/auth",service="bkrepo",scope="repository:*/*/tb:push,pull"
nginx 配置
server {
listen 2443;
#server_name 域名;
access_log logs/access_hub.log main;
#ssl_certificate 证书地址;
#ssl_certificate_key 密钥地址;
#ssl_session_timeout 24h;
#ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
#ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
location /v2/ {
proxy_pass https://xxxx/v2/; # Docker Hub 的官方镜像仓库
proxy_set_header Host xxxxx;
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="http://192.168.74.100:2443/v2/auth",service="xxxxx"' 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;
}
location @handle_redirect {
#resolver 1.1.1.1;
set $saved_redirect_location '$upstream_http_location';
proxy_pass $saved_redirect_location;
}
}
docker 配置
cat /etc/docker/daemon.json
{
"insecure-registries":[
192.168.74.100:2443
]
}
docker 镜像下载验证
将hub域名替换成192.168.74.100:2443
代理前下载方式:
docker pull nginx
代理后下载方式:
docker pull 192.168.74.100:2443/nginx
4层代理
本地 hosts 配置
192.168.74.100 xxxxxx # Docker Hub 的官方镜像仓库
nginx 配置
server {
listen 443; # 本地监听端口
proxy_pass xxxxx:443; # Docker Hub 的官方镜像仓库
proxy_connect_timeout 5s; # 连接超时时间
proxy_timeout 360s; # 代理超时时间
}
访问实例
docke login xxxxx # Docker Hub 的官方镜像仓库