前言

因为总总原因,导致现在大多数的docker hub镜像加速站都停止服务,而docker hub官方站点又因为某些原因访问不到或者延迟很高。所以,介绍一种通过白嫖 CloudFlare 搭建一个自己的docker hub 镜像加速服务。

白嫖 CloudFlare 的 Workers 你需要做下面几个准备:

  • 登录 CloudFlare 官网,并注册一个账户;
  • 注册一个 cn 域名(推荐腾讯云),DNS填写 CloudFlare 中的即可(可选,因为CloudFlare提供的访问域名很长,转移到CloudFlare后不需要备案)
  • 选择Free计划,创建一个Workers。免费的Workers 有用量限制,如下图:
    cloudflare free 计划对比

一、注册账户和域名

  1. 注册 CloudFlare 账户很简单,打开官网,填写邮箱和密码注册就行了(后续使用时才会校验邮箱)。
    cloudflare注册

  2. 注册域名,直接打开 推荐腾讯云 链接,选个便宜的cn或者top域名即可。
    腾讯云域名购买

二、创建 Workers

  1. 创建 Workers 需要校验邮箱,在主页面右侧导航栏点击 Workers 和 Pages,然后点击 create workers 按钮,会提示先校验邮箱
    校验邮箱

  2. 邮箱校验成功后,继续点击 create workers,workers 名称这里可以做修改,修改完成后,点击保存(最终会用这个作为访问url,绑定自己域名的可以不用管)。
    命名worker,下面就是访问这个worker的域名

  3. 这里先不用管,直接点击完成(finish)。
    worker代码,先不用管

  4. 完成后,点击右上角的 编辑(edit code)
    创建完成,编辑代码

  5. 将 worker.js 里面的代码,用下面的代码替换。

import HTML from './index.html';
export default {
    async fetch(request) {
        const url = new URL(request.url);
        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);
        console.log(registryResponse.status);
        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 {
        return new Response(HTML.replace(/{{host}}/g, originalHost), {
            status: 200,
            headers: {
            "content-type": "text/html"
            }
        });
        }
    }
}

workerjs代码

  1. 创建一个新文件,命名为 index.html,复制下面代码:
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>镜像使用说明</title>
  <style>
    body {
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
      margin: 0;
      padding: 0;
      background-color: #f0f2f5;
      display: flex;
      flex-direction: column;
      min-height: 100vh;
    }
    .header {
      background: linear-gradient(90deg, #4e54c8 0%, #8f94fb 100%);
      color: white;
      text-align: center;
      padding: 20px 0;
    }
    .container {
      flex: 1;
      display: flex;
      justify-content: center;
      align-items: center;
      padding: 20px;
    }
    .content {
      background: white;
      border-radius: 8px;
      box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
      padding: 20px;
      max-width: 800px; /* 调整后的宽度 */
      width: 100%;
      font-size: 16px; /* 放大字体 */
    }
    .code-block {
      background: #2d2d2d;
      color: #f8f8f2;
      padding: 10px;
      border-radius: 8px;
      margin: 10px 0;
      overflow-x: auto;
      font-family: "Courier New", Courier, monospace; /* 保持代码块的字体 */
    }
    .footer {
      background: #444;
      color: white;
      text-align: center;
      padding: 5px 0; /* 调低高度 */
    }
    .footer a {
      color: #4caf50;
      text-decoration: none;
    }
    @media (max-width: 600px) {
      .content {
        padding: 10px;
        font-size: 14px; /* 在小屏幕上稍微减小字体 */
      }
    }
  </style>
</head>
<body>
  <div class="header">
    <h1>镜像使用说明</h1>
  </div>
  <div class="container">
    <div class="content">
      <p>要设置加速镜像服务,你可以执行下面命令:</p>
      <div class="code-block">
        <pre>
sudo tee /etc/docker/daemon.json &lt;&lt;EOF
{
	"registry-mirrors": ["https://这里修改成你的workers访问地址"]
}
EOF
        </pre>
      </div>
	  <p>如果执行了上述命令,配置了镜像加速服务,可以直接 pull 镜像:</p>
      <div class="code-block">
        <pre>
docker pull ubuntu:latest # 拉取 ubuntu 镜像
        </pre>
      </div>
	  <p>因为Workers用量有限,在使用加速镜像服务时,你可以手动 pull 镜像然后 re-tag 之后 push 至本地镜像仓库:</p>
      <div class="code-block">
        <pre>
docker pull 这里修改成你的workers访问地址/library/ubuntu:latest # 拉取 ubuntu 镜像
        </pre>
      </div>
    </div>
  </div>
  <div class="footer">
    <p>Powered by Cloudflare Workers</p>
    <p><a href="https://blog.cmyang.cn">访问博客 blog.cmyang.cn</a></p>
  </div>
</body>
</html>

index代码
注意:上述代码中的访问地址要替换成 cloudflare分配给你的workers地址,也可以是自己的自定义域名(需要配置)

  1. 点击右上角的 部署 按钮,选择 保存并部署
    部署按钮,马赛克位置即为当前服务访问地址

  2. 部署成功后,通过cloudflare给定的域名可以打开一个页面:
    镜像加速服务web界面

最后

最后贴一张使用docker pull 镜像的图。关于cloudflare绑定自定义域名的问题,在这里因为篇幅问题就不再赘述,因为免费提供的域名也能够访问。
有需要的可以看上一篇文章:实用教程:如何通过CloudFlare添加自己的域名站点,创建自定义域访问Worker服务

docker镜像加速拉取