轻量级 Docker 镜像代理服务,旨在解决国内访问 Docker Hub 受限问题。
更名说明: 本项目已由 Docxy 更名为 Wharf。后续二进制命令、安装目录、systemd 服务和 Release 产物统一使用
wharf;旧文档或博客中出现的 Docxy 指向同一个项目。
-
🚀 一键部署: 提供
install.sh自动化脚本,可一键完成环境配置、证书申请 (Let's Encrypt)、服务部署,无需手动干预。 -
📦 多种部署模式:
- 独立运行: 内置 TLS 功能,直接对外提供 HTTPS 服务。
- Nginx 代理: 可配合 Nginx 作为后端服务运行。
- CDN 回源: 支持 HTTP 模式,方便接入 CDN。
-
⚡ 支持登录提升速率: 允许用户通过
docker login使用个人账户认证,将匿名用户的拉取速率限制(10次/小时/IP)提升至认证用户的(100次/小时/账户)。 -
💎 完全透明的代理: 完美兼容 Docker Registry V2 API,客户端仅需修改镜像源地址,无额外学习成本和使用习惯的改变。
-
🛡️ 高性能与安全: 基于 Rust 和 Actix Web 构建,性能卓越、内存安全。采用流式传输处理镜像,开销极小。
我们提供了一键安装脚本来简化部署流程,在开始前,请提前将您的域名解析到目标主机。
bash <(curl -Ls https://raw.githubusercontent.com/harrisonwang/wharf/main/install.sh)脚本将引导您完成安装,并提供以下三种部署模式:
这是最简单、最推荐的模式。Wharf 将直接监听 80 和 443 端口,对外提供完整的 HTTPS 代理服务。
特点:
- 无需额外配置 Web 服务器。
- 自动处理 HTTP 到 HTTPS 的重定向。
- 可选择自动申请 Let's Encrypt 证书或使用您自己的证书。
安装流程:
- 运行一键安装脚本。
- 在模式选择时,输入
1或直接回车。 - 根据提示输入您的域名,并选择证书处理方式。
- 脚本将自动完成所有配置并启动服务。
模式二:Nginx 反向代理 (高级)
此模式适用于您已经拥有并希望通过 Nginx 统一管理 Web 服务的场景。
特点:
- 由 Nginx 统一处理 HTTPS 加密和证书管理,Wharf 在后端以普通 HTTP 模式运行。
- Wharf 作为后端 HTTP 服务运行在一个指定端口上 (如: 9000)。
- 方便与其他服务集成。
安装流程:
- 运行一键安装脚本。
- 在模式选择时,输入
2。 - 根据提示输入您的域名、Wharf 后端监听端口以及证书信息。
- 脚本会自动为您生成一份 Nginx 配置文件示例,您需要手动将其添加到您的 Nginx 配置中,并重载 Nginx 服务。
模式三:CDN 回源 (HTTP) (高级)
此模式适用于您希望将 Wharf 作为 CDN 的源站,以获得更好的全球加速效果。
特点:
- Wharf 仅监听 HTTP 端口。
- 由 CDN 服务商负责处理 HTTPS 请求和证书。
- Wharf 会信任并处理
X-Forwarded-*头,以正确识别客户端 IP 和协议。
安装流程:
- 运行一键安装脚本。
- 在模式选择时,输入
3。 - 根据提示输入 Wharf 需要监听的 HTTP 端口。
- 配置您的 CDN 服务,将源站指向 Wharf 服务的地址和端口。
配置 Docker 客户端以使用您的代理服务。
这是最基础的配置,将 Docker 的默认请求指向您的代理服务。
-
配置 Docker Daemon
编辑
/etc/docker/daemon.json文件 (如果不存在则创建),并添加以下内容。将your-domain.com替换为您的域名。{ "registry-mirrors": ["https://your-domain.com"] } -
重启 Docker 服务
sudo systemctl restart docker
现在,
docker pull将通过您的代理进行拉取。
Wharf 支持在同一个服务进程中配置多个上游仓库。Docker Hub 仍可通过 registry-mirrors 使用;GHCR、Quay.io 等非 Docker Hub 仓库需要使用对应的代理域名拉取。
示例配置:
[registry]
default = "dockerhub"
[[registry.upstreams]]
name = "dockerhub"
hosts = ["docker.example.com"]
upstream_registry = "https://registry-1.docker.io"
auth_realm = "https://auth.docker.io/token"
auth_service = "registry.docker.io"
auto_library_prefix = true
public_base_url = "https://docker.example.com"
[[registry.upstreams]]
name = "ghcr"
hosts = ["ghcr.example.com"]
upstream_registry = "https://ghcr.io"
auth_realm = "https://ghcr.io/token"
auth_service = "ghcr.io"
auto_library_prefix = false
public_base_url = "https://ghcr.example.com"
[[registry.upstreams]]
name = "quay"
hosts = ["quay.example.com"]
upstream_registry = "https://quay.io"
auth_realm = "https://quay.io/v2/auth"
auth_service = "quay.io"
auto_library_prefix = false
public_base_url = "https://quay.example.com"使用示例:
docker pull ghcr.example.com/owner/image:tag
docker pull quay.example.com/organization/image:tag
docker login ghcr.example.com
docker login quay.example.com方式二:登录使用 (提升拉取速率)
此方式可以在匿名使用的基础上,通过登录您的 Docker Hub 账户来获取更高的镜像拉取速率。
-
完成基础配置
请确保您已经完成了 方式一 中的所有步骤。
-
登录代理服务
使用
docker login命令并输入您的 Docker Hub 用户名和密码。docker login your-domain.com
-
同步认证信息
登录成功后,需要手动编辑
~/.docker/config.json文件,将您刚刚为your-domain.com生成的auth信息,复制一份给https://index.docker.io/v1/。修改前:
{ "auths": { "your-domain.com": { "auth": "aBcDeFgHiJkLmNoPqRsTuVwXyZ..." } } }修改后:
{ "auths": { "your-domain.com": { "auth": "aBcDeFgHiJkLmNoPqRsTuVwXyZ..." }, "https://index.docker.io/v1/": { "auth": "aBcDeFgHiJkLmNoPqRsTuVwXyZ..." } } }保存文件后,您的
docker pull请求就会以认证用户的方式发送,从而享受更高的速率限制。
Note
详细的技术背景、系统架构和实现流程,请参阅 技术架构与原理文档。
-
克隆仓库
git clone https://github.com/harrisonwang/wharf.git cd wharf -
修改配置文件 打开
config/default.toml.example,复制为config/default.toml,然后修改配置。开发调试时建议本地跑 HTTP(8080),通过 Tunnel 对外提供 HTTPS 域名。cp config/default.toml.example config/default.toml
然后编辑
config/default.toml:# config/default.toml [server] http_port = 8080 # 使用非特权端口 https_port = 8443 http_enabled = true # 启用 HTTP https_enabled = false # 禁用 HTTPS behind_proxy = true public_base_url = "https://your-dev-domain.example" # 必须填写 Tunnel 暴露给外网的地址 [registry] default = "dockerhub" upstream_registry = "https://registry-1.docker.io" auth_realm = "https://auth.docker.io/token" auth_service = "registry.docker.io" auto_library_prefix = true [tls] cert_path = "/tmp/wharf-dev.crt" key_path = "/tmp/wharf-dev.key"
说明:
public_base_url必须与外部真实访问地址完全一致(协议/域名/端口)。- 当
https_enabled = false时,本地不会读取证书文件;但当前配置结构仍要求保留[tls]字段,可使用占位路径。
-
运行项目 现在,可以直接用
cargo运行项目。cargo run
服务将启动并监听在
http://0.0.0.0:8080。 -
通过 Tunnel 暴露公网域名(便于本地联调) 在另一个终端启动隧道,将公网请求转发到本地
8080。以下命令为示例,具体参数以各服务商文档为准。# ngrok ngrok http 8080 # tunnl.gg(示例) ssh -N -R <subdomain>:80:127.0.0.1:8080 <tunnl-endpoint> # localhost.run ssh -N -R 80:127.0.0.1:8080 nokey@localhost.run
例如你使用固定二级域名
example.com时:public_base_url应设置为https://example.com- 隧道命令可用:
ssh -N -R dev:80:127.0.0.1:8080 ssh.edge.ng
-
验证链路
curl -i https://your-dev-domain.example/health curl -i https://your-dev-domain.example/v2/ curl -i http://127.0.0.1:8080/v2/ -H 'Host: evil.test'预期:
WWW-Authenticate中的realm固定指向public_base_url,不受Host头影响。 -
构建发布版本
cargo build --release
本项目采用 MIT 许可证,查看 LICENSE 了解更多信息。