Docker拉取镜像方法

​ 众所周知,现阶段dockerhub已经失联,而平常工作或是学习都需要拉取一些Docker镜像,由此带来了很多不方便,虽然自己使用可以通过全局代理等方式来用,但是分享给别人或是不在本地使用,就会陷入麻烦,这里也是收集了网络上的一些常见解决方法,虽然是拾人牙慧,自己也经过了一些验证,确定了当前环境真正可用的方法并做下记录。

自建registry

​ 这种方法应该是最标准、也是最适用于企业环境的方法了,不过对于个人来说不太实用,需要一台海外服务器。这里不再赘述详细方法,相关记录很容易找到。

Cloudflare Workers代理

​ 这种方法对于个人来说最实用、成本最低,仅需要一个域名就可以解决,虽然会有访问速度不稳定的问题。不过我的使用cloudflare家产品比较少,所以没有实践这种方法。相关的方法其他人的博客中说的很清楚,可以参考附上的链接。

Nginx反向代理

​ 这是我实践最多的一个方法,因为我的服务器上已经部署了nginx。本以为会非常容易实现,不过网上大部分方法的配置都无法跑通。根据一篇博客中的抓包详情,不仅要反代registry,还要代理auth、production,而大部分给出的nginx配置都只反代了registry。

​ 这里还是给出我测试能够正常pull的nginx配置,这种方法也是其他博客中提供的,我使用的certbot自动化配置证书,所以删去了原文中关于ssl的配置:

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
# 使用 map 来匹配和替换 upstream 头部中的 auth.docker.io
map $upstream_http_www_authenticate $m_www_authenticate_replaced {
"~auth\.docker\.io(.*)" "$1";
default "";
}

map $m_www_authenticate_replaced $m_final_replaced {
"~(.*)" 'Bearer realm=\"$scheme://$host$1';
default "";
}

server
{
listen 80;
# 改成自己的域名
server_name your.domain.com;

# 修改jwt授权地址
proxy_hide_header www-authenticate;
add_header www-authenticate "$m_final_replaced" always;

# 关闭缓存
proxy_buffering off;
# 转发认证相关
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;

# 对 upstream 状态码检查,实现 error_page 错误重定向
proxy_intercept_errors on;
recursive_error_pages on;
# 根据状态码执行对应操作,以下为301、302、307状态码都会触发
error_page 301 302 307 = @handle_redirect;

# v1 api
location /v1 {
proxy_pass https://index.docker.io;
proxy_set_header Host index.docker.io;
}

# v2 api
location /v2 {
proxy_pass https://index.docker.io;
proxy_set_header Host index.docker.io;
}

# jwt授权地址
location /token {
proxy_pass https://auth.docker.io;
proxy_set_header Host auth.docker.io;
}

location / {
# Docker hub 的官方镜像仓库
proxy_pass https://registry-1.docker.io;
proxy_set_header Host registry-1.docker.io;
}

#处理重定向
location @handle_redirect {
resolver 1.1.1.1;
set $saved_redirect_location '$upstream_http_location';
proxy_pass $saved_redirect_location;
}
}

​ 另外看到一个使用caddy的反代方法,由于对于nginx和caddy都不太熟练,把caddy转成nginx配置始终有点问题。对于nginx的配置还有待后续学习。

本地代理

​ 这种方法对于本地或是局域网环境最方便。早期一直想给Docker配置代理,但始终不行,后面就改用阿里云的镜像加速了。也是在最近才知道,大部分的Docker都是apt或者yum安装的,因此他的服务被systemd接管了,如果要设置代理,需要修改systemd的配置文件。当然修改docker的daemon文件也可行。(这只是设置docker pull的代理,docker run/build 的代理方法与此不同)

​ 修改或创建/etc/docker/daemon.json

1
2
3
4
5
6
7
{
"proxies": {
"http-proxy": "http://127.0.0.1:1080",
"https-proxy": "https://127.0.0.1:1080",
"no-proxy": "*.test.example.com,.example.org,127.0.0.0/8"
}
}

​ 修改或创建/etc/systemd/system/docker.service.d/http-proxy.conf

1
2
3
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:8123"
Environment="HTTPS_PROXY=http://127.0.0.1:8123"
参考链接

https://zhul.in/2024/09/21/how-to-reverse-proxy-dockerhub-with-caddy/index.html

https://www.iszy.cc/posts/nginx-docker-hub/

https://blog.hentioe.dev/posts/unhindered-accesss-dockerhub.html