【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

2024-08-02 13:50:11 31点赞 375收藏 15评论

之前写过一篇关于在NAS中部署游戏的攻略,后台有粉丝反映他的Docker镜像不能拉取。

本期文章通过Cloudflare Workers搭建一个免费的Docker镜像加速。跟着本文步骤操作,小白也可以部署成功。

搭建准备:一个域名+一个Cloudflare账户。Cloudflare账户注册很简单,搜索Cloudflare即可注册,本文的域名是在腾讯云购买(域名需要付费)。

文章目录

一、域名注册

二、域名托管至Cloudflare

三、在Cloudflare部署服务

四、Container 部署

一、域名注册

登录腾讯云进行注册。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

根据自己的预算和需求选择想要的域名,点击添加购物车,然后进行购买。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

购买之前需要进行实名认证,官方给的消息是1~N个工作日,我大概三十分钟实名认证成功,认证成功后,接着去购买自己想要的域名。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

购买成功后,这里还需要对域名进行审核,同业也是说需要N个工作日后能审核成功,差不多一个小时后就审核通过,服务状态这里就显示正常。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

登录腾讯云DNSPOD

浏览器搜索DNSPOD进入,然后登录控制台。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

登录后,点击头像,接着点击API密钥。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

 

然后新建API密钥。注意:API密钥是构建腾讯云APIA请求的重要凭证,不要外泄,要妥善保存。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

创建Token:新建完密钥后,转到DNSPod Token

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

输入密钥名称,方便管理。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

创建完密钥后,后跳出以下弹窗,DNSPod 不会存储原始密钥,将以上的信息只出现一次,可以保存在笔记本中。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

 

二、域名托管至Cloudflare

登入Cloudflare 后,点击添加站点。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

输入上面在腾讯云申请的域名。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

接着往下拉选择免费的。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

接着下来可以看到Cloudflare 分配的两个服务器名称,需要返回到腾讯云,添加分配的这两个 Cloudflare 名称服务器,删除任何其他名称服务器,然后保存更改。

 

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

返回到腾讯云,修改DNS服务器。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

点击自定义DNS,将上面分配的两个 Cloudflare 名称服务器复制到这里。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

回到Cloudflare ,左上角显示已激活,右下方的基本功能进行启用。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

 

三、在Cloudflare部署服务

 进入Cloudflare主页面,按照下图依次点击Workers和Pages→创建Workers。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

登录前需要进行邮箱验证。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

下图位置输入docker,然后进行部署。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

部署完成后,点击编辑代码。

 

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

代码如下

'use strict'; const hub_host = 'registry-1.docker.io'; const auth_url = 'https://auth.docker.io'; const workers_url = 'https://你的域名'; 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 (!/%2F/.test(url.search) && /%3A/.test(url.toString())) { let modifiedUrl = url.toString().replace(/%3A(?=.*?&)/, '%3Alibrary%2F'); url = new URL(modifiedUrl); } 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); } if (/^/v2/[^/]+/[^/]+/[^/]+$/.test(url.pathname) && !/^/v2/library/.test(url.pathname)) { url.pathname = url.pathname.replace(//v2//, '/v2/library/'); } 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 = await original_response_clone.text(); 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; if (req.method === 'OPTIONS' && reqHdrRaw.has('access-control-request-headers')) { return new Response(null, PREFLIGHT_INIT); } let rawLen = ''; const reqHdrNew = new Headers(reqHdrRaw); let urlStr = pathname; const urlObj = newUrl(urlStr); const reqInit = { method: req.method, headers: reqHdrNew, redirect: 'follow', body: req.body }; return proxy(urlObj, reqInit, rawLen); } async function proxy(urlObj, reqInit, rawLen) { const res = await fetch(urlObj.href, reqInit); const resHdrOld = res.headers; const resHdrNew = new Headers(resHdrOld); 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 }); }

粘贴完代码点击部署。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

返回上一菜单,找到设置→触发器→添加定义域。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

 

笔者这里输入docker+申请的域名。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

接着等待域名证书发放,几分钟就可以成功,在等待期间去点击右上角【编辑代码】。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

把如下位置,填上自己的域名,按照下图格式填写。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

部署完就结束了。

四、Container 部署

回到威联通NAS进入 Container Station,进入存储库→添加。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

按照下图填写,测试连接不要忘记点。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

接着在【映像】中点击提取,同样按照下图操作,最后提取。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

这样就部署成功了,接下来进行测试,提取之前一个游戏的映像名称。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

可以成功提取。

【保姆级攻略】Docker 镜像提取失败?一文轻松搞定

希望本期文章对你有所帮助,感兴趣的朋友可以点赞收藏关注,咱们下期见!

展开 收起
15评论

  • 精彩
  • 最新
  • 很及时,周末搞 [欢呼]

    校验提示文案

    提交
    [ok了] 按着步骤来很简单的

    校验提示文案

    提交
    收起所有回复
  • 不是说挂这个被cf封号了吗

    校验提示文案

    提交
    自己玩玩 别刷太多流量

    校验提示文案

    提交
    收起所有回复
  • 群晖怎么设置更换

    校验提示文案

    提交
    没设置过群辉的呢,应该都差不多

    校验提示文案

    提交
    好的,感谢马上再试试

    校验提示文案

    提交
    收起所有回复
  • cloudflare里面没有workers和pages这个选项啊

    校验提示文案

    提交
    我这里能看到,在电子邮件安全下面

    校验提示文案

    提交
    收起所有回复
  • 碰到同样问题,代码粘贴后报错,uncaught syntaxerror invaild regular expression flags at worker.js 71:8(code 10021)

    校验提示文案

    提交
    可能平台吞格式了

    校验提示文案

    提交
    收起所有回复
  • 很急时,正好需要感恩 [抽烟]

    校验提示文案

    提交
  • dnspod不是白设置了?

    校验提示文案

    提交
  • 代码复制后提交不对,能不能再发下代码

    校验提示文案

    提交
  • 代码错误,21个错误无法部署

    校验提示文案

    提交
提示信息

取消
确认
评论举报

相关文章推荐

更多精彩文章
更多精彩文章
最新文章 热门文章
375
扫一下,分享更方便,购买更轻松