群晖更换docker加速源

群晖更换docker加速源

代码搬运工
2024-06-16 / 0 评论 / 76 阅读 / 正在检测是否收录...
近期由于种种原因,国内的docker镜像源纷纷被禁,群晖也是只能查询镜像,但是无法pull,从网上查了很多方案,发现一种通过cloudflare的 worker服务代理的方式,这种方式个人感觉比较简单有效方法推荐给大家。

前提条件

  1. 注册一个域名。 域名注册可以选择国内的腾讯云、阿里云等,新人注册一般会有较大的优惠,如果不想花钱,网上也有免费注册域名的教程,比如eu.org( https://nic.eu.org ),虽然免费,但是审核周期比较长,大家可自行选择。
  2. 注册cloudflare账号。 注册环节比较简单,此处不再过多赘述,附上注册地址: 点击跳转

开始部署

1、登录 Cloudflare 账号,进入到主页,点击“网站”菜单,添加站点,这里我添加一个已经注册好的域名。

lxhfwhrt.png

lxhfx5yt.png

2、选择计划。这里选择免费计划Free即可,免费计划已经完全能够满足我们的使用,具体的区别可自行对比(计划对比 )。

lxhdyvz7.png

3、修改DNS服务器。首先点击“开始快速扫描”,之后点击“继续”,下面需要我们修改域名的DNS服务地址,以腾讯云为例,首先前往“我的域名”,找到我们的域名,点击更多,选择“修改DNS服务器”,之后选择“自定义DNS”,把刚才cloudflare提供给我们的名称服务器填上,然后返回cloudflare,点击继续,之后就等待cloudflare验证通过后会通过邮件的形式告知我们。

lxhe0aqp.png

lxhe6gho.png

lxhe8krg.png

lxhebdrf.png

lxhedmp3.png

lxheilcg.png

4、自定义一个DNS记录。域名验证通过后,我们进入域名的网站,点击DNS菜单中的设置,我们添加一个A记录,名称随便起一个,这里叫docker吧,ipv4地址随便填,这里填8.8.8.8,启用代理。
lxhelbp5.png

lxheq47r.png

5、创建Workers。回到cloudflare首页,选择“Workers 和 Pages菜单”,点击左侧“创建”,填一下名字,这里叫“dockerhub”,点击保存、完成,之后点击右上角“编辑代码”,把下面的代码粘贴进去(PS:代码是从网上找的,看懂原理,大家可自行编辑),修改workers_url为上一步添加的A记录域名,之后点击右上角“部署”,然后回到项目页面,点击“设置”-》“触发器”-》添加路由,路由填刚才添加的A记录域名,后面一定要加上/*,区域选择我们的域名就可以了。

lxheu21b.png

lxhevyeu.png

lxhex79w.png

lxhey7v7.png

'use strict'
const hub_host = 'registry-1.docker.io'
const auth_url = 'https://auth.docker.io'
// 请将 workers_url替换成自己的域名
const workers_url = ''
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',
    }),
}
function makeRes(body, status = 200, headers = {}) {
    headers['access-control-allow-origin'] = '*'
    return new Response(body, {status, headers})
}
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)
})
async function fetchHandler(e) {
  const getReqHeader = (key) => e.request.headers.get(key);
  let url = new URL(e.request.url);
  if (url.pathname === '/token') {
      let token_parameter = {
        headers: {
        'Host': 'auth.docker.io',
        'User-Agent': getReqHeader("User-Agent"),
        'Accept': getReqHeader("Accept"),
        'Accept-Language': getReqHeader("Accept-Language"),
        'Accept-Encoding': getReqHeader("Accept-Encoding"),
        'Connection': 'keep-alive',
        'Cache-Control': 'max-age=0'
        }
      };
      let token_url = auth_url + url.pathname + url.search
      return fetch(new Request(token_url, e.request), token_parameter)
  }
  url.hostname = hub_host;
  let parameter = {
    headers: {
      'Host': hub_host,
      'User-Agent': getReqHeader("User-Agent"),
      'Accept': getReqHeader("Accept"),
      'Accept-Language': getReqHeader("Accept-Language"),
      'Accept-Encoding': getReqHeader("Accept-Encoding"),
      'Connection': 'keep-alive',
      'Cache-Control': 'max-age=0'
    },
    cacheTtl: 3600
  };
  if (e.request.headers.has("Authorization")) {
    parameter.headers.Authorization = getReqHeader("Authorization");
  }
  let original_response = await fetch(new Request(url, e.request), parameter)
  let original_response_clone = original_response.clone();
  let original_text = original_response_clone.body;
  let response_headers = original_response.headers;
  let new_response_headers = new Headers(response_headers);
  let status = original_response.status;
  if (new_response_headers.get("Www-Authenticate")) {
    let auth = new_response_headers.get("Www-Authenticate");
    let re = new RegExp(auth_url, 'g');
    new_response_headers.set("Www-Authenticate", response_headers.get("Www-Authenticate").replace(re, workers_url));
  }
  if (new_response_headers.get("Location")) {
    return httpHandler(e.request, new_response_headers.get("Location"))
  }
  let response = new Response(original_text, {
            status,
            headers: new_response_headers
        })
  return response;
}
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)
    }
    let rawLen = ''
    const reqHdrNew = new Headers(reqHdrRaw)
    const refer = reqHdrNew.get('referer')
    let urlStr = pathname
    const urlObj = newUrl(urlStr)
    /** @type {RequestInit} */
    const reqInit = {
        method: req.method,
        headers: reqHdrNew,
        redirect: 'follow',
        body: req.body
    }
    return proxy(urlObj, reqInit, rawLen, 0)
}
async function proxy(urlObj, reqInit, rawLen) {
    const res = await fetch(urlObj.href, reqInit)
    const resHdrOld = res.headers
    const resHdrNew = new Headers(resHdrOld)
    // verify
    if (rawLen) {
        const newLen = resHdrOld.get('content-length') || ''
        const badLen = (rawLen !== newLen)
        if (badLen) {
            return makeRes(res.body, 400, {
                '--error': `bad len: ${newLen}, except: ${rawLen}`,
                'access-control-expose-headers': '--error',
            })
        }
    }
    const status = res.status
    resHdrNew.set('access-control-expose-headers', '*')
    resHdrNew.set('access-control-allow-origin', '*')
    resHdrNew.set('Cache-Control', 'max-age=1500')
    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
    })
}

lxhf1w1h.png

lxhf4wio.png

lxhf7kov.png

6、验证结果。我们用ssh命令进入群晖,使用 sudo -i 命令切换到root用户,下面我们来验证一下操作结果。

# 使用curl命令,返回404
curl https://docker.***
404 page not found

# 拉取nginx镜像,能够成功拉取表示成功
docker pull https://docker.***/library/nginx:latest

7、替换群晖docker镜像加速地址,进入群晖的Container Manager,点击“注册表”-》“设置”,选择“Docker Hub (v1)”,,点击“编辑”,勾选“启用注册表镜像”,填上我们刚才配置的A记录域名,然后我们删除掉上一步拉取的nginx镜像,尝试直接执行 docker pull nginx:latest ,能够拉取则证明成功了。

lxhffddk.png

lxhfhpdo.png

1

评论 (0)

取消