一分钱不花,让 Docker 镜像飞起来——Cloudflare Workers 白嫖指南

0 阅读6分钟

一分钱不花,让 Docker 镜像飞起来——Cloudflare Workers 白嫖指南

国内拉取 Docker 镜像有多难?就像让鸽子给你送快递——不是丢件就是慢如蜗牛。 今天教你一招:用 Cloudflare 的免费羊毛,搭一个属于自己的镜像加速器,一劳永逸。

前言:为什么你要看这篇文章?

如果你曾在国内服务器上执行过 docker pull,大概率遇到过这些情况:

  • 进度条卡在 Waiting 十几分钟不动
  • 好不容易开始下载,速度却不如 2G 网络
  • 错误提示 connection reset by peeri/o timeout

这是因为 Docker Hub 的官方服务器在国外,国内网络访问经常被“温柔地”限速或阻断。 公共镜像源基本已经不再免费。

有没有一个完全免费、速度飞快、还属于自己的加速方案? 有!用 Cloudflare Workers 搭一个代理。 Cloudflare 是什么?全球最大的 CDN 服务商,免费套餐每天送 10 万次请求,对于个人或小团队来说绰绰有余。 你只需要一个域名和十分钟,就能让你的 Docker 拉取体验像坐火箭。

第一步:注册 Cloudflare 账号

  1. 访问 Cloudflare 官网,点击“注册”。

  2. 输入邮箱和密码,验证邮箱后登录。

  3. 进入控制台 dash.cloudflare.com

    登录后,如果有提示,一路选择第一项。不需要添加任何站点,直接点击左侧菜单的 Workers 和 Pages

1.png

如果你是第一次使用,Cloudflare 可能会引导你添加站点,直接跳过即可。

第二步:创建 Worker

  1. 点击 创建应用程序创建 Worker

2.png

  1. 选择Hello World开始!给你的 Worker 起个名字,比如 docker-proxy(随便起,代码后面再改)。

  2. 直接点击 部署

此时你有了一个默认的 Worker 地址:https://docker-proxy.你的用户名.workers.dev。 但这只是个 Hello World,现在我们要把它变成真正的镜像加速器。

第三步:部署多仓库代理代码

我们要让一个 Worker 同时代理 Docker HubKubernetes 官方镜像仓库(registry.k8s.ioQuay.io。 这样你只需一个 Worker,就能覆盖绝大部分镜像需求。

1. 编辑 Worker 代码

在 Worker 页面点击 编辑代码,删除所有默认内容,粘贴以下代码(注意!!一定要替换你的域名):

// 上游仓库映射
const upstreamMap = {
  "bhz-docker-proxy.你的域名": {
    registry: "https://registry-1.docker.io",
    auth: "https://auth.docker.io"
  },
  "bhz-k8s-proxy.你的域名": {
    registry: "https://registry.k8s.io",
    auth: null
  },
  "bhz-quay-proxy.你的域名": {
    registry: "https://quay.io",
    auth: "https://quay.io"
  }
};
​
async function handleRequest(request) {
  const url = new URL(request.url);
  const host = url.hostname;
  const path = url.pathname;
  const search = url.search;
​
  const config = upstreamMap[host];
  if (!config) {
    return new Response(`No upstream configured for host: ${host}`, { status: 404 });
  }
​
  const upstreamRegistry = config.registry;
  const authService = config.auth;
​
  // 处理 token 请求
  if (path === '/token' && authService) {
    const tokenResp = await fetch(`${authService}/token${search}`, {
      headers: request.headers,
    });
    return new Response(tokenResp.body, {
      status: tokenResp.status,
      headers: tokenResp.headers,
    });
  }
​
  // 发起上游请求(不自动跟随重定向)
  const upstreamUrl = `${upstreamRegistry}${path}${search}`;
  let resp = await fetch(upstreamUrl, {
    method: request.method,
    headers: request.headers,
    redirect: 'manual',
  });
​
  // 内部跟随重定向(最多 5 次)
  let redirectCount = 0;
  const maxRedirects = 5;
  while ((resp.status === 301 || resp.status === 302 || resp.status === 307 || resp.status === 308) && redirectCount < maxRedirects) {
    const location = resp.headers.get('Location');
    if (!location) break;
​
    let nextUrl;
    try {
      nextUrl = new URL(location, upstreamUrl);
    } catch (e) {
      break;
    }
​
    // 如果是相对路径,补全
    const nextRequest = new Request(nextUrl, {
      method: request.method,
      headers: request.headers,
      redirect: 'manual',
    });
    resp = await fetch(nextRequest, { redirect: 'manual' });
    redirectCount++;
  }
​
  // 构建响应
  const response = new Response(resp.body, {
    status: resp.status,
    statusText: resp.statusText,
    headers: resp.headers,
  });
​
  // 处理 401(认证地址替换)
  if (resp.status === 401 && authService) {
    const authHeader = resp.headers.get('www-authenticate');
    if (authHeader) {
      const newAuthHeader = authHeader.replace(authService, `https://${host}`);
      response.headers.set('www-authenticate', newAuthHeader);
    }
  }
​
  // 清理可能暴露的内部头信息
  response.headers.delete('x-redirect-count');
  return response;
}
​
addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request));
});

2. 修改域名映射

把代码最上面的 upstreamMap 里的 "你的域名" 换成 你自己的域名(子域名随意,比如 docker.你的域名.com`)。

3. 保存并部署

点击右上角 保存并部署

第四步:绑定自定义域名

虽然 Workers 自带 *.workers.dev 域名,但在国内基本被限速或阻断。 绑定自己的域名可以完美解决这个问题,而且看起来更专业。

1. 将域名托管到 Cloudflare

如果你还没有把域名托管给 Cloudflare,需要先在 Cloudflare 中添加站点,并修改域名的 NS 记录。 !!注意: 最好用一个空域名。不然你还要导入其他解析记录。

虽然说是托管后其他子域名(比如 wwwmail)不受影响,可以单独控制每个子域名是否走 Cloudflare 代理。但是我并没有测试哈哈。

托管步骤:

在Cloudflare端加入域名,属于域名后,它会给你提供ns记录。这个记录需要你去域名注册商那里修改为cloudflare提供的ns。

3.png

2. 添加自定义域

  • 进入你的 Worker → 点击 触发器自定义域添加自定义域
  • 输入你配置文件中的域名,比如 docker.你的域名.com。不要写错。
  • 重复上述步骤,依次添加 k8s.你的域名.comquay.你的域名.com

4.png

Cloudflare 会自动添加 DNS 记录并签发 SSL 证书,几分钟后生效。

3. 验证域名解析

ping docker.你的域名.com

如果返回 Cloudflare 的 IP(如 104.21.x.x),说明绑定成功。

第五步:测试并配置 Docker 客户端

现在你有两种方式使用加速服务:

docker pull bhz-quay-proxy.你的域名.com/prometheus/busybox:latest
docker pull bhz-k8s-proxy.你的域名.com/pause:3.9
docker pull bhz-docker-proxy.你的域名.com/library/alpine:latest

6.png

如果都成功,恭喜!你已经拥有了一台免费、高速、专属的 Docker 镜像加速器。

Docker全局镜像加速器设置

编辑 /etc/docker/daemon.json(Linux)或 Docker Desktop 设置(Windows/macOS):

{
  "registry-mirrors": [
    "https://docker.你的域名.com",
    "https://k8s.你的域名.com",
    "https://quay.你的域名.com"
  ]
}

重启 Docker:

sudo systemctl restart docker

containerd镜像通用,只是方式不一样,就不在此赘述了。

查看资源消耗状态:

7.png

为什么这个方案这么香?

  1. 完全免费:Cloudflare Workers 每天 10 万次请求,个人用根本用不完。
  2. 全球加速:Cloudflare 有 280+ 边缘节点,国内访问速度比直连 Docker Hub 快几倍。
  3. 一劳永逸:一次部署,永久有效。不用再担心公共镜像源挂掉或限速。
  4. 支持多仓库:Docker Hub、K8s、Quay 都能代理,覆盖日常开发 90% 的镜像需求。
  5. 安全可控:所有流量经过你的域名,不用担心第三方镜像源篡改或植入恶意代码。

注意事项

  • 免费额度:每天 10 万次请求,对于个人或小团队完全够用。但如果被恶意刷量,可以设置防火墙规则或增加认证。
  • 域名备案:如果你的服务器在国内,且使用自定义域名,建议域名已备案,否则可能被运营商拦截。但使用 *.workers.dev 域名则无需备案。
  • K8s 镜像的重定向registry.k8s.io 会返回 307 重定向到实际存储地址,代码已内置跟随重定向逻辑,放心使用。
  • Quay.io 认证:Quay 的认证地址与 Docker Hub 略有不同,但上述代码已处理,一般都能正常工作。

写在最后

如果你以前觉得搭建自己的镜像加速器需要买服务器、配 Nginx、折腾 SSL 证书,现在有了 Cloudflare Workers,一切都变得简单。 这套方案我已经在生产环境跑了半年,稳如老狗。 希望你的 Docker 拉取从此告别龟速,享受火箭般的速度。

!如果觉得有用,欢迎分享给更多被 Docker 镜像折磨的朋友。 白嫖有理,加速无罪! 🚀

彩蛋:如果你不想用自己的域名,可以直接用 Worker 默认的 *.workers.dev 地址,虽然部分地区可能稍慢,但也能用。

进阶玩法:你可以用这个 Worker 代理其他任何 OCI 镜像仓库,只需在 upstreamMap 中增加配置即可。