利用Cloudflare Workers轻松搭建免费Docker Hub镜像加速器

### **利用Cloudflare Workers轻松搭建免费Docker Hub镜像加速器** #### **前言:为什么要自建加速器?** 对于许多开发者来说,直接从 Docker Hub 拉取镜像时常会遇到速度缓慢甚至连接失败的问题。这严重影响了开发和部署效率。虽然存在一些公共的镜像加速服务,但它们可能不稳定或存在安全隐患。 本教程将指导您如何利用 Cloudflare 强大且免费的 Workers 服务,搭建一个属于您自己的、稳定高效的 Docker Hub 镜像加速器。整个过程无需服务器,只需一个域名,即可享受 Cloudflare 全球CDN网络带来的极速体验。 **核心优势:** * **完全免费**:Cloudflare Workers 的免费套餐提供每日10万次请求,对于个人或小型团队的日常使用綽綽有餘。 * **性能卓越**:借助 Cloudflare 的全球分布式网络,您的 Docker 拉取请求将被路由到最近的节点,大大提升下载速度。 * **无需维护**:基于 Serverless 架构,您无需关心服务器的购买、配置和运维。 * **高安全性**:所有流量均通过您自己的 Cloudflare 账户,安全可控。 #### **准备工作** 在开始之前,请确保您已准备好以下两项: 1. **一个 Cloudflare 账户**:如果还没有,可以前往 [Cloudflare官网](https://dash.cloudflare.com/) 免费注册。 2. **一个您自己的域名**:您可以在任何域名注册商处购买。推荐使用价格便宜的 `.xyz`、`.top` 等域名。购买后,需要将该域名的 DNS 管理权交由 Cloudflare。 > **如何将域名交给 Cloudflare 管理?** > 1. 登录 Cloudflare,点击“添加站点”。 > 2. 输入您购买的域名,选择免费计划。 > 3. Cloudflare 会扫描您现有的 DNS 记录,并提供两个 Cloudflare 的**名称服务器 (Nameserver)**地址。 > 4. 回到您购买域名的平台(如GoDaddy、NameSilo等),找到 DNS 设置,将默认的名称服务器更改为 Cloudflare 提供的那两个。 > 5. 等待几分钟到几小时,DNS 全球生效后,您的域名就成功由 Cloudflare 解析和管理了。 --- ### **详细搭建步骤** #### **第一步:创建 Cloudflare Worker** 1. 登录到您的 [Cloudflare 仪表盘](https://dash.cloudflare.com/)。 2. 在左侧导航栏中,找到并点击 **Workers 和 Pages**。 3. 点击 **创建应用程序** > **创建 Worker**。 4. 为您的 Worker 指定一个易于记忆的名称,例如 `docker-mirror`。这个名称将成为 Worker 的初始子域名的一部分(如 `docker-mirror.your-worker-name.workers.dev`)。 5. 点击 **部署**。一个包含默认代码的 Worker 就创建并部署成功了。 #### **第二步:配置 Worker 核心代码** 接下来,我们需要将默认代码替换为我们的代理逻辑代码。 1. 在 Worker 的管理界面,点击 **编辑代码** 按钮。 2. 您会看到一个在线代码编辑器,其中有一个 `index.js` 或 `_worker.js` 文件。**删除其中的所有默认代码**,然后将下面的代码完整地复制粘贴进去。 **`_worker.js` 代码:** ```javascript /** * Docker Hub a reverse proxy for Cloudflare Workers * * @author BiliBili-jz * @see https://github.com/BiliBili-jz/docker-hub-mirror * * Please check the latest version of the worker script from the above address * and deploy it to your Cloudflare account. */ // 镜像仓库地址 const hub_host = 'registry-1.docker.io' // 自定义脚本(如果不需要可以设置为 "" 或 null) // 例如,您可以创建一个 Gist 或其他静态文本服务来存放一个 shell 脚本, // 用户通过 `curl -fsSL your-domain.com | sh` 即可自动配置 Docker。 const custom_script = "https://gist.githubusercontent.com/BiliBili-jz/345424747a9e6a048701a2d16918d363/raw/install.sh" export default { async fetch(request, env, ctx) { let url = new URL(request.url) const path = url.pathname // 处理根路径或特定路径的请求,提供使用说明 if (path === '/' || path.startsWith('/v2/')) { // 如果是 v2 API 路径,则进行代理 if (path.startsWith('/v2/')) { return proxyToDockerHub(request, path) } // 否则,提供一个友好的使用说明页面 const worker_domain = url.hostname const html = await generateUsagePage(worker_domain) return new Response(html, { status: 200, headers: { 'Content-Type': 'text/html; charset=utf-8', }, }) } // 处理自定义安装脚本 else if (custom_script && (path === '/install' || path === '/install.sh')) { return fetch(custom_script) } // 其他所有未知路径返回 404 else { return new Response('Not Found', { status: 404 }) } }, } /** * 代理请求到 Docker Hub * @param {Request} request 原始请求 * @param {string} path 请求路径 * @returns {Promise} */ async function proxyToDockerHub(request, path) { const registry_url = new URL(path, 'https://' + hub_host) const new_headers = new Headers(request.headers) new_headers.set('Host', hub_host) // 创建一个新的请求以转发到 Docker Hub const proxy_request = new Request(registry_url, { method: request.method, headers: new_headers, body: request.body, redirect: 'follow', // 遵循重定向 }) // 发起请求 const response = await fetch(proxy_request) // 处理响应头,特别是针对认证的 WWW-Authenticate 头 if (path === '/v2/' && response.status === 401) { const new_response_headers = new Headers(response.headers) const auth_header = new_response_headers.get('WWW-Authenticate') // 重写认证域名,确保客户端能正确回调到我们的 Worker if (auth_header) { const new_auth_header = auth_header.replace( 'auth.docker.io', new URL(request.url).hostname ) new_response_headers.set('WWW-Authenticate', new_auth_header) } return new Response(response.body, { status: response.status, statusText: response.statusText, headers: new_response_headers, }) } // 对于 Docker OAuth 认证回调的特殊处理 else if ( path.startsWith('/v2/auth') || path.startsWith('/token') || path.startsWith('/v2/token') ) { const auth_url_obj = new URL(request.url) const service = auth_url_obj.searchParams.get('service') const scope = auth_url_obj.searchParams.get('scope') // 将请求转发到正确的 Docker 认证服务 return fetch(`https://auth.docker.io/token?service=${service}&scope=${scope}`) } return response } /** * 生成一个美观且信息丰富的使用说明页面 * @param {string} host Worker 的域名 * @returns {string} HTML 字符串 */ async function generateUsagePage(host) { // 动态生成使用说明,避免硬编码 return ` Docker 镜像加速服务

Docker 镜像加速服务已就绪

此服务由 Cloudflare Workers 强力驱动,旨在为您提供更快速、更稳定的 Docker 镜像拉取体验。

配置 Docker 加速器

请创建或修改 /etc/docker/daemon.json 文件(如果文件不存在,请新建),并加入以下内容。请务必将 ${host} 替换为您自己的加速域名。

{
  "registry-mirrors": ["https://${host}"]
}

修改配置后,请不要忘记重启 Docker 服务以使配置生效:

sudo systemctl daemon-reload
sudo systemctl restart docker

手动拉取镜像示例

如果您不想修改全局配置,也可以在拉取镜像时手动指定加速地址:

# 拉取官方的 Ubuntu 镜像
docker pull ${host}/library/ubuntu:latest

# 拉取 k8s 使用的 coredns 镜像
docker pull ${host}/coredns/coredns:latest

# 拉取后可以重新打标签为原始名称
docker tag ${host}/library/ubuntu:latest ubuntu:latest
` } ``` 3. 粘贴完代码后,点击右上角的 **保存并部署** 按钮。您的 Worker 代理服务现在已经启动并运行了! #### **第三步:绑定自定义域名** 直接使用 `workers.dev` 的子域名也可以,但它较长且不便于记忆。绑定到您自己的域名下是更好的选择。 1. 返回到 `docker-mirror` Worker 的管理页面,选择 **触发器 (Triggers)** 标签页。 2. 在“自定义域”部分,点击 **添加自定义域**。 3. 输入一个您想用于加速服务的子域名,例如 `docker.yourdomain.com` (请将 `yourdomain.com` 替换为您自己的域名)。 4. 点击 **添加**。Cloudflare 会自动为您处理 SSL 证书和 DNS 解析记录,稍等片刻即可生效。 至此,您的专属 Docker 镜像加速器已全部搭建完成!它的访问地址就是您刚刚绑定的 `https://docker.yourdomain.com`。 --- ### **如何使用您的加速服务** 现在,您可以将 Docker 客户端配置为使用这个新的加速地址了。 #### **方法一:全局配置(推荐)** 这是最方便的方法,一次配置,永久生效。 1. 打开终端,编辑 Docker 的配置文件 `daemon.json`。在 Linux 系统上,它通常位于 `/etc/docker/daemon.json`。 ```bash sudo nano /etc/docker/daemon.json ``` 2. 将以下内容复制进去。**注意:** 请将 `docker.yourdomain.com` 替换为您上一步绑定的真实域名! ```json { "registry-mirrors": ["https://docker.yourdomain.com"] } ``` > 如果该文件已有内容,请确保 `registry-mirrors` 是一个 JSON 数组,并将您的域名添加进去。 3. 保存文件并退出编辑器。 4. 重启 Docker 服务以应用新的配置。 ```bash sudo systemctl daemon-reload sudo systemctl restart docker ``` 5. 可以通过 `docker info` 命令来验证加速器是否配置成功。在输出的信息中,查找 "Registry Mirrors" 部分,如果能看到您的域名,就说明配置成功了。 #### **方法二:手动拉取指定镜像** 如果您只是临时需要加速某个镜像,或者不想修改全局配置,可以采用手动指定的方式。 语法是在镜像名称前加上您的加速域名和斜杠。 ```bash # 通过加速器拉取官方的 Nginx 镜像 docker pull docker.yourdomain.com/library/nginx:latest # 拉取后,您可以为其重新打上一个简短的标签,方便使用 docker tag docker.yourdomain.com/library/nginx:latest nginx:latest ``` ### **总结与提醒** 通过以上步骤,您已经成功地为自己构建了一个私有、免费且高效的 Docker Hub 镜像加速器。这不仅解决了网络访问问题,还让您对整个流程有了更深入的理解。 * **注意用量**:请留意 Cloudflare 的免费套餐限制(每日10万次请求)。对于个人使用来说是完全足够的,但请避免公开分享您的加速地址,以免额度被耗尽。 * **访问验证**:您可以直接在浏览器中访问您的加速域名(例如 `https://docker.yourdomain.com`),如果看到美观的使用说明页面,说明 Worker 部署成功。 祝您编码愉快!

发表评论

0 评论