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

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

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

文章目录

一、域名注册

二、域名托管至Cloudflare

三、在Cloudflare部署服务

四、Container 部署

一、域名注册

登录腾讯云进行注册。

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

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

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

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

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

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

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

登录腾讯云DNSPOD

地址:https://www.dnspod.cn/login?login_jump=yes&s_url=https://console.dnspod.cn/dns/list&sync_code=1

【保姆级攻略】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 镜像提取失败?一文轻松搞定

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

,

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。