基于cloudflare-workers搭建docker镜像代理

在国内正常拉取 docker官方仓库镜像

1.登录cloudflare

没有账户,注册一个

2.cloudflare workers

2.1 cloudflare介绍

3bd46bf1c957475cb17816b13025274b.png

7e38c7853a51c21687727b3ea08b2eb0.png

195175407921e31f48c4a788db3a6888.png

4aba2bc480c63b809de632170107e1e2.png

5a3dd500751df84de575c9e7fd8e6d32.png

71a4f676adbd4f2bf1bec493a1d0a9ae.png

2.2部署work.js及验证拉取

登录cloudflare创建worker项目,点击部署

063d33f43d68179a8d95efd3c5fc33c0.png

进入编辑代码复制work.js,进行部署

docker.js -> work.js(专门针对dockerhub加速)

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
function logError(request, message) {
console.error(
`${message}, clientIp: ${request.headers.get(
"cf-connecting-ip"
)}, user-agent: ${request.headers.get("user-agent")}, url: ${request.url}`
);
}

function createNewRequest(request, url, proxyHostname, originHostname) {
const newRequestHeaders = new Headers(request.headers);
for (const [key, value] of newRequestHeaders) {
if (value.includes(originHostname)) {
newRequestHeaders.set(
key,
value.replace(
new RegExp(`(?<!\\.)\\b${originHostname}\\b`, "g"),
proxyHostname
)
);
}
}
return new Request(url.toString(), {
method: request.method,
headers: newRequestHeaders,
body: request.body,
});
}

function setResponseHeaders(
originalResponse,
proxyHostname,
originHostname,
DEBUG
) {
const newResponseHeaders = new Headers(originalResponse.headers);
for (const [key, value] of newResponseHeaders) {
if (value.includes(proxyHostname)) {
newResponseHeaders.set(
key,
value.replace(
new RegExp(`(?<!\\.)\\b${proxyHostname}\\b`, "g"),
originHostname
)
);
}
}
if (DEBUG) {
newResponseHeaders.delete("content-security-policy");
}
let docker_auth_url = newResponseHeaders.get("www-authenticate");
if (docker_auth_url && docker_auth_url.includes("auth.docker.io/token")) {
newResponseHeaders.set(
"www-authenticate",
docker_auth_url.replace("auth.docker.io/token", originHostname + "/token")
);
}
return newResponseHeaders;
}

/**
* 替换内容
* @param originalResponse 响应
* @param proxyHostname 代理地址 hostname
* @param pathnameRegex 代理地址路径匹配的正则表达式
* @param originHostname 替换的字符串
* @returns {Promise<*>}
*/
async function replaceResponseText(
originalResponse,
proxyHostname,
pathnameRegex,
originHostname
) {
let text = await originalResponse.text();
if (pathnameRegex) {
pathnameRegex = pathnameRegex.replace(/^\^/, "");
return text.replace(
new RegExp(`((?<!\\.)\\b${proxyHostname}\\b)(${pathnameRegex})`, "g"),
`${originHostname}$2`
);
} else {
return text.replace(
new RegExp(`(?<!\\.)\\b${proxyHostname}\\b`, "g"),
originHostname
);
}
}

async function nginx() {
return `<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>`;
}

export default {
async fetch(request, env, ctx) {
try {
let {
PROXY_HOSTNAME = "registry-1.docker.io",
PROXY_PROTOCOL = "https",
PATHNAME_REGEX,
UA_WHITELIST_REGEX,
UA_BLACKLIST_REGEX,
URL302,
IP_WHITELIST_REGEX,
IP_BLACKLIST_REGEX,
REGION_WHITELIST_REGEX,
REGION_BLACKLIST_REGEX,
DEBUG = false,
} = env;
const url = new URL(request.url);
const originHostname = url.hostname;
if (url.pathname.includes("/token")) {
PROXY_HOSTNAME = "auth.docker.io";
} else if (url.pathname.includes("/search")) {
PROXY_HOSTNAME = "index.docker.io";
}
if (
!PROXY_HOSTNAME ||
(PATHNAME_REGEX && !new RegExp(PATHNAME_REGEX).test(url.pathname)) ||
(UA_WHITELIST_REGEX &&
!new RegExp(UA_WHITELIST_REGEX).test(
request.headers.get("user-agent").toLowerCase()
)) ||
(UA_BLACKLIST_REGEX &&
new RegExp(UA_BLACKLIST_REGEX).test(
request.headers.get("user-agent").toLowerCase()
)) ||
(IP_WHITELIST_REGEX &&
!new RegExp(IP_WHITELIST_REGEX).test(
request.headers.get("cf-connecting-ip")
)) ||
(IP_BLACKLIST_REGEX &&
new RegExp(IP_BLACKLIST_REGEX).test(
request.headers.get("cf-connecting-ip")
)) ||
(REGION_WHITELIST_REGEX &&
!new RegExp(REGION_WHITELIST_REGEX).test(
request.headers.get("cf-ipcountry")
)) ||
(REGION_BLACKLIST_REGEX &&
new RegExp(REGION_BLACKLIST_REGEX).test(
request.headers.get("cf-ipcountry")
))
) {
logError(request, "Invalid");
return URL302
? Response.redirect(URL302, 302)
: new Response(await nginx(), {
headers: {
"Content-Type": "text/html; charset=utf-8",
},
});
}
url.host = PROXY_HOSTNAME;
url.protocol = PROXY_PROTOCOL;
const newRequest = createNewRequest(
request,
url,
PROXY_HOSTNAME,
originHostname
);
const originalResponse = await fetch(newRequest);
const newResponseHeaders = setResponseHeaders(
originalResponse,
PROXY_HOSTNAME,
originHostname,
DEBUG
);
const contentType = newResponseHeaders.get("content-type") || "";
let body;
if (contentType.includes("text/")) {
body = await replaceResponseText(
originalResponse,
PROXY_HOSTNAME,
PATHNAME_REGEX,
originHostname
);
} else {
body = originalResponse.body;
}
return new Response(body, {
status: originalResponse.status,
headers: newResponseHeaders,
});
} catch (error) {
logError(request, `Fetch error: ${error.message}`);
return new Response("Internal Server Error", { status: 500 });
}
},
};

进入项目设置,自定义域名加速及dockerhub加速host
0ff8e1108a3e25a71cf16119cab68d3c.png

配置docker damon.json 镜像加速
systemctl daemon-reload && systemctl restart docker

{
    ...
      "registry-mirrors": [
        "https://xxxx"
        ],
    ....
}

拉取镜像验证
docker pull rokcylinux:8

643e5d4c79b3b42f11a44e182d16c509.png

可观测日志开启(查看拉取情况)
07233b9e49cb29afdccdb586488c2720.png