阅读之前
请注意:实现搭建docker镜像中转,需要满足以下条件,如不满足请不要复现浪费时间。
- 拥有一个自己的域名
- 域名通过cloudflare的DNS进行解析,可以在cloudflar中阅读帮助进行解析
注册并登录CF账号
https://dash.cloudflare.com/login?lang=zh-hans-cn
建立worker
-
创建worker
-
配置worker
-
开始编辑代码
-
编辑代码
在左侧代码去执行:
- 删除全部默认代码
- 添加以下代码
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 });
}
},
};
- 点击右上角“部署”
- 点击左上角向前返回
设置worker
- 设置选项
- 添加自己的域名
配置docker镜像
- 在目标服务器配置docker镜像下载站
vi /etc/docker/daemon.json
在"registry-mirrors"字段添加自己的域名
- 拉取镜像测试
docker pull redis