===============
== ffff65535 ==
===============
十六个一[1111111111111111]

自建 GitHub 加速服务:从 CF Workers 迁移到 VPS 部署 hubproxy + Caddy

docker hubproxy caddy github-proxy vps reverse-proxy

之前用的 gh-proxy,基于 Cloudflare Workers 搭建。现在换了新域名 1s.gs,改用 hubproxy 部署在自己的 VPS 上,完全自托管,不再依赖第三方服务。


架构

用户 → 1s.gs → Caddy (:80/:443) → hubproxy (:5000)
                    ↕
            hubproxy_net Docker 网络
  • Caddy 负责 HTTPS 和反代
  • hubproxy 不暴露端口,仅通过 Docker 内部网络通信
  • 旧域名 github-proxy.top 显示迁移提示页,3 秒后跳转到新域名

步骤

1. 部署 hubproxy

mkdir -p /opt/services/hubproxy

/opt/services/hubproxy/docker-compose.yml

services:
  hubproxy:
    image: ghcr.io/sky22333/hubproxy:latest
    container_name: hubproxy
    restart: always
    volumes:
      - ./config.toml:/app/config.toml:ro
    networks:
      - hubproxy_net

networks:
  hubproxy_net:
    external: true

/opt/services/hubproxy/config.toml

⚠️ 必须配置!hubproxy 默认安全白名单只允许 172.17.0.0/16(Docker 默认 bridge),而自定义 Docker 网络是 172.18.0.0/16,不加白名单会被 403 拦截。

[security]
whiteList = ["127.0.0.1", "172.17.0.0/16", "172.18.0.0/16", "你的公网IP"]

2. 部署 Caddy

mkdir -p /opt/services/caddy

/opt/services/caddy/docker-compose.yml

services:
  caddy:
    image: caddy:2-alpine
    container_name: caddy-hubproxy
    restart: always
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - ./caddy_data:/data
      - ./caddy_config:/config
    networks:
      - hubproxy_net

networks:
  hubproxy_net:
    external: true

3. Caddyfile

完整配置(双域名):

github-proxy.top {
        header Content-Type "text/html; charset=utf-8"

        @root path /
        handle @root {
                respond / "..." 200
                header / Refresh "3; url=https://1s.gs"
        }
        handle {
                respond * "..." 200
                header * Refresh "3; url=https://1s.gs{uri}"
        }
}

1s.gs {
        reverse_proxy hubproxy:5000 {
                header_up X-Real-IP {remote_host}
                header_up X-Forwarded-For {remote_host}
                header_up X-Forwarded-Proto {scheme}
        }
}

respond 中的 HTML 是渐变紫背景的迁移提示页,包含"这个域名快退休了"、“1s.gs"可长按复制、收藏按钮、3 秒自动跳转。

启动:

docker network create hubproxy_net

cd /opt/services/hubproxy && docker compose up -d
cd /opt/services/caddy && docker compose up -d

踩坑记录

坑 1:hubproxy 返回 403

原因: hubproxy 的安全白名单默认只包含 172.17.0.0/16,自定义 Docker 网络 hubproxy_net172.18.0.0/16,不在白名单内。

解决:config.toml 中把自定义网络网段和公网 IP 加入白名单。

坑 2:{remote} 带端口号

原因: Caddy 的 {remote} 变量包含端口号(如 1.2.3.4:55612),hubproxy 拿这个做安全匹配时白名单中的纯 IP 对不上。

解决: 改用 {remote_host},只传纯 IP 不带端口:

header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}

坑 3:Docker Compose v5 网络语法

Compose v5 不再支持在 service 内联写法 external: true,需要在顶级 networks: 块声明:

# ❌ 旧写法
services:
  xxx:
    networks:
      hubproxy_net:
        external: true

# ✅ 正确写法
services:
  xxx:
    networks:
      - hubproxy_net

networks:
  hubproxy_net:
    external: true

坑 4:Caddy respond 返回 text/plain

原因: Caddy 的 respond 指令默认 Content-Type 是 text/plain,浏览器按纯文本渲染 HTML。

解决:file_server 服务静态 HTML 文件,或确保 respond 配合 header 设置正确的 Content-Type。


效果

  • https://1s.gs → hubproxy 自带前端页面
  • https://1s.gs/https://github.com/user/repo/... → 正常加速代理
  • https://github-proxy.top → 渐变紫提示页,3 秒后跳转新域名

参考