需要vps的
https://github.com/dqzboy/Docker-Proxy
基于CF Worker的(待补充)
可参考旧的链接:cfworker docker,github反代加速 - 时空云博客
github
需要vps的
https://github.com/WJQSERVER-STUDIO/ghproxy
基于CF Worker的
使用cf大善人的服务
创建worker后把js粘贴到对应地方就行,在设置-触发器绑定自己域名(需要在cf的NS记录)
github:
github.876436.xyz
'use strict'/**
* static files (404.html, sw.js, conf.js)
*/const ASSET_URL = 'https://hunshcn.github.io/gh-proxy/'// 前缀,如果自定义路由为example.com/gh/*,将PREFIX改为 '/gh/',注意,少一个杠都会错!const PREFIX = '/'// 分支文件使用jsDelivr镜像的开关,0为关闭,默认关闭const Config = { jsdelivr: 0}const whiteList = [] // 白名单,路径里面有包含字符的才会通过,e.g. ['/username/']/** @type {ResponseInit} */const PREFLIGHT_INIT = { status: 204, headers: new Headers({ 'access-control-allow-origin': '*', 'access-control-allow-methods': 'GET,POST,PUT,PATCH,TRACE,DELETE,HEAD,OPTIONS', 'access-control-max-age': '1728000',
}),
}const exp1 = /^(?:https?:\/\/)?github\.com\/.+?\/.+?\/(?:releases|archive)\/.*$/iconst exp2 = /^(?:https?:\/\/)?github\.com\/.+?\/.+?\/(?:blob|raw)\/.*$/iconst exp3 = /^(?:https?:\/\/)?github\.com\/.+?\/.+?\/(?:info|git-).*$/iconst exp4 = /^(?:https?:\/\/)?raw\.(?:githubusercontent|github)\.com\/.+?\/.+?\/.+?\/.+$/iconst exp5 = /^(?:https?:\/\/)?gist\.(?:githubusercontent|github)\.com\/.+?\/.+?\/.+$/iconst exp6 = /^(?:https?:\/\/)?github\.com\/.+?\/.+?\/tags.*$/i/**
* @param {any} body
* @param {number} status
* @param {Object<string, string>} headers
*/function makeRes(body, status = 200, headers = {}) {
headers['access-control-allow-origin'] = '*'
return new Response(body, {status, headers})
}/**
* @param {string} urlStr
*/function newUrl(urlStr) { try { return new URL(urlStr)
} catch (err) { return null
}
}
addEventListener('fetch', e => { const ret = fetchHandler(e)
.catch(err => makeRes('cfworker error:\n' + err.stack, 502))
e.respondWith(ret)
})function checkUrl(u) { for (let i of [exp1, exp2, exp3, exp4, exp5, exp6]) { if (u.search(i) === 0) { return true
}
} return false}/**
* @param {FetchEvent} e
*/async function fetchHandler(e) { const req = e.request const urlStr = req.url const urlObj = new URL(urlStr) let path = urlObj.searchParams.get('q') if (path) { return Response.redirect('https://' + urlObj.host + PREFIX + path, 301)
} // cfworker 会把路径中的 `//` 合并成 `/`
path = urlObj.href.substr(urlObj.origin.length + PREFIX.length).replace(/^https?:\/+/, 'https://') if (path.search(exp1) === 0 || path.search(exp5) === 0 || path.search(exp6) === 0 || path.search(exp3) === 0 || path.search(exp4) === 0) { return httpHandler(req, path)
} else if (path.search(exp2) === 0) { if (Config.jsdelivr) { const newUrl = path.replace('/blob/', '@').replace(/^(?:https?:\/\/)?github\.com/, 'https://cdn.jsdelivr.net/gh') return Response.redirect(newUrl, 302)
} else {
path = path.replace('/blob/', '/raw/') return httpHandler(req, path)
}
} else if (path.search(exp4) === 0) { const newUrl = path.replace(/(?<=com\/.+?\/.+?)\/(.+?\/)/, '@$1').replace(/^(?:https?:\/\/)?raw\.(?:githubusercontent|github)\.com/, 'https://cdn.jsdelivr.net/gh') return Response.redirect(newUrl, 302)
} else { return fetch(ASSET_URL + path)
}
}/**
* @param {Request} req
* @param {string} pathname
*/function httpHandler(req, pathname) { const reqHdrRaw = req.headers // preflight
if (req.method === 'OPTIONS' &&
reqHdrRaw.has('access-control-request-headers')
) { return new Response(null, PREFLIGHT_INIT)
} const reqHdrNew = new Headers(reqHdrRaw) let urlStr = pathname let flag = !Boolean(whiteList.length) for (let i of whiteList) { if (urlStr.includes(i)) {
flag = true
break
}
} if (!flag) { return new Response("blocked", {status: 403})
} if (urlStr.search(/^https?:\/\//) !== 0) {
urlStr = 'https://' + urlStr
} const urlObj = newUrl(urlStr) /** @type {RequestInit} */
const reqInit = { method: req.method, headers: reqHdrNew, redirect: 'manual', body: req.body
} return proxy(urlObj, reqInit)
}/**
*
* @param {URL} urlObj
* @param {RequestInit} reqInit
*/async function proxy(urlObj, reqInit) { const res = await fetch(urlObj.href, reqInit) const resHdrOld = res.headers const resHdrNew = new Headers(resHdrOld) const status = res.status if (resHdrNew.has('location')) { let _location = resHdrNew.get('location') if (checkUrl(_location))
resHdrNew.set('location', PREFIX + _location) else {
reqInit.redirect = 'follow'
return proxy(newUrl(_location), reqInit)
}
}
resHdrNew.set('access-control-expose-headers', '*')
resHdrNew.set('access-control-allow-origin', '*')
resHdrNew.delete('content-security-policy')
resHdrNew.delete('content-security-policy-report-only')
resHdrNew.delete('clear-site-data') return new Response(res.body, {
status, headers: resHdrNew,
})
}docker:
docker.876436.xyz
const HTML = `<!DOCTYPE html><html lang="zh-CN"><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dockerhub镜像加速说明</title>
<style>
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; line-height: 1.6; color: #333; margin: 0; padding: 20px; background-image: url('https://cdn.jsdelivr.net/gh/fireinrain/picx-images-hosting@master/20240608/wp8114669-docker-wallpapers.5h6dvj56isg0.webp'); /* Replace with your image path */
background-size: cover; background-position: center; background-repeat: no-repeat; background-attachment: fixed;
} .container { max-width: 800px; margin: 0 auto; padding: 20px; background: rgba(255, 255, 255, 0.8); border-radius: 8px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
} h1 { font-size: 2em; margin-bottom: 0.5em; color: #007aff;
} p { margin-bottom: 1em;
}
pre { background: #2d2d2d; color: #f8f8f2; padding: 20px; border-radius: 8px; overflow-x: auto; position: relative;
}
pre::before { content: " "; display: block; position: absolute; top: 10px; left: 10px; width: 12px; height: 12px; background: #ff5f56; border-radius: 50%; box-shadow: 20px 0 0 #ffbd2e, 40px 0 0 #27c93f;
} code { font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 0.875em;
} .copy-button { position: absolute; top: 10px; right: 10px; background: #007aff; color: white; border: none; padding: 5px 10px; border-radius: 5px; cursor: pointer; opacity: 0; transition: opacity 0.3s;
}
pre:hover .copy-button { opacity: 1;
}</style></head><body>
<div class="container">
<center><h1>镜像加速说明</h1></center>
<h3>为了加速镜像拉取,你可以使用以下命令设置 registry mirror:</h3>
<pre><code>sudo tee /etc/docker/daemon.json <<EOF{
"registry-mirrors": ["https://docker.yourdomain.workers.dev"]
}EOF</code><button class="copy-button" onclick="copyCode(this)">复制代码</button></pre>
<h3>用法:</h3>
<p>原拉取镜像命令</p>
<pre><code>docker pull library/alpine:latest</code><button class="copy-button" onclick="copyCode(this)">复制代码</button></pre>
<h3>加速拉取镜像命令</h3>
<pre><code>docker pull 你的域名/library/alpine:latest</code><button class="copy-button" onclick="copyCode(this)">复制代码</button></pre>
</div>
<script>
function copyCode(button) { const code = button.previousSibling; const textArea = document.createElement('textarea');
textArea.value = code.textContent; document.body.appendChild(textArea);
textArea.select(); document.execCommand('copy'); document.body.removeChild(textArea);
button.textContent = '已复制'; setTimeout(() => {
button.textContent = '复制代码';
}, 2000);
}</script></body></html>`;
async function handleRequest(request) {
const url = new URL(request.url);
// Redirect to HTTPS if the request is not secure
if (url.protocol !== "https:") {
url.protocol = "https:";
return Response.redirect(url.toString(), 301);
}
const path = url.pathname;
const originalHost = request.headers.get("host");
const registryHost = "registry-1.docker.io";
if (path.startsWith("/v2/")) {
const headers = new Headers(request.headers);
headers.set("host", registryHost);
const registryUrl = `https://${registryHost}${path}`;
const registryRequest = new Request(registryUrl, {
method: request.method,
headers: headers,
body: request.body,
redirect: "follow",
});
const registryResponse = await fetch(registryRequest);
const responseHeaders = new Headers(registryResponse.headers);
responseHeaders.set("access-control-allow-origin", originalHost);
responseHeaders.set("access-control-allow-headers", "Authorization");
return new Response(registryResponse.body, {
status: registryResponse.status,
statusText: registryResponse.statusText,
headers: responseHeaders,
});
} else {
// Replace docker.yourdomain.workers.dev with the current visiting domain
const replacedHTML = HTML.replaceAll('docker.yourdomain.workers.dev', originalHost);
// Remove background-image from btn-copy buttons
const modifiedHTML = replacedHTML.replace(/background-image:\s*url\(.*?\)/g, '');
return new Response(modifiedHTML, {
status: 200,
headers: {
"content-type": "text/html"
}
});
}
}
addEventListener("fetch", event => {
event.respondWith(handleRequest(event.request));
});打赏
支付宝微信扫一扫,打赏作者吧~

支付宝微信扫一扫,打赏作者吧~本文链接:https://www.kinber.cn/post/6739.html 转载需授权!
推荐本站淘宝优惠价购买喜欢的宝贝:

