An open API service indexing awesome lists of open source software.

https://github.com/harrisonwang/wharf

Docker Hub proxy service
https://github.com/harrisonwang/wharf

docker proxy registry

Last synced: 5 days ago
JSON representation

Docker Hub proxy service

Awesome Lists containing this project

README

          

# Wharf

![og-image](og-image.svg)

[![English](https://img.shields.io/badge/English-Click-orange)](README_EN.md)
[![简体中文](https://img.shields.io/badge/简体中文-点击查看-blue)](README.md)
[![Русский](https://img.shields.io/badge/Русский-Нажмите-orange)](README_RU.md)
[![Español](https://img.shields.io/badge/Español-Clic-blue)](README_ES.md)
[![한국어](https://img.shields.io/badge/한국어-클릭-orange)](README_KR.md)
[![العربية](https://img.shields.io/badge/العربية-انقر-blue)](README_AR.md)
[![Türkçe](https://img.shields.io/badge/Türkçe-Tıkla-orange)](README_TR.md)

轻量级 Docker 镜像代理服务,旨在解决国内访问 Docker Hub 受限问题。

> **更名说明:** 本项目已由 **Docxy** 更名为 **Wharf**。后续二进制命令、安装目录、systemd 服务和 Release 产物统一使用 `wharf`;旧文档或博客中出现的 Docxy 指向同一个项目。

> 📢 **使用教程:** [**跟 Docker Hub 连接超时说拜拜!用 Wharf 自建专属镜像加速器**](https://voxsay.com/posts/docxy-docker-proxy-tutorial-for-china/)

## 核心特性

* 🚀 **一键部署**: 提供 `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
bash <(curl -Ls https://raw.githubusercontent.com/harrisonwang/wharf/main/install.sh)
```

脚本将引导您完成安装,并提供以下三种部署模式:

---

### 模式一:独立运行 (HTTPS)

这是最简单、最推荐的模式。Wharf 将直接监听 80 和 443 端口,对外提供完整的 HTTPS 代理服务。

**特点:**
- 无需额外配置 Web 服务器。
- 自动处理 HTTP 到 HTTPS 的重定向。
- 可选择自动申请 Let's Encrypt 证书或使用您自己的证书。

**安装流程:**
1. 运行一键安装脚本。
2. 在模式选择时,输入 `1` 或直接回车。
3. 根据提示输入您的域名,并选择证书处理方式。
4. 脚本将自动完成所有配置并启动服务。

---

模式二:Nginx 反向代理 (高级)

### 模式二:Nginx 反向代理

此模式适用于您已经拥有并希望通过 Nginx 统一管理 Web 服务的场景。

**特点:**
- 由 Nginx 统一处理 HTTPS 加密和证书管理,Wharf 在后端以普通 HTTP 模式运行。
- Wharf 作为后端 HTTP 服务运行在一个指定端口上 (如: 9000)。
- 方便与其他服务集成。

**安装流程:**
1. 运行一键安装脚本。
2. 在模式选择时,输入 `2`。
3. 根据提示输入您的域名、Wharf 后端监听端口以及证书信息。
4. 脚本会自动为您生成一份 Nginx 配置文件示例,您需要手动将其添加到您的 Nginx 配置中,并重载 Nginx 服务。

---

模式三:CDN 回源 (HTTP) (高级)

### 模式三:CDN 回源 (HTTP)

此模式适用于您希望将 Wharf 作为 CDN 的源站,以获得更好的全球加速效果。

**特点:**
- Wharf 仅监听 HTTP 端口。
- 由 CDN 服务商负责处理 HTTPS 请求和证书。
- Wharf 会信任并处理 `X-Forwarded-*` 头,以正确识别客户端 IP 和协议。

**安装流程:**
1. 运行一键安装脚本。
2. 在模式选择时,输入 `3`。
3. 根据提示输入 Wharf 需要监听的 HTTP 端口。
4. 配置您的 CDN 服务,将源站指向 Wharf 服务的地址和端口。

## Docker 客户端使用

配置 Docker 客户端以使用您的代理服务。

### 方式一:匿名使用 (基础配置)

这是最基础的配置,将 Docker 的默认请求指向您的代理服务。

1. **配置 Docker Daemon**

编辑 `/etc/docker/daemon.json` 文件 (如果不存在则创建),并添加以下内容。将 `your-domain.com` 替换为您的域名。

```json
{
"registry-mirrors": ["https://your-domain.com"]
}
```

2. **重启 Docker 服务**

```bash
sudo systemctl restart docker
```
现在,`docker pull` 将通过您的代理进行拉取。

### 多仓库代理

Wharf 支持在同一个服务进程中配置多个上游仓库。Docker Hub 仍可通过 `registry-mirrors` 使用;GHCR、Quay.io 等非 Docker Hub 仓库需要使用对应的代理域名拉取。

示例配置:

```toml
[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"
```

使用示例:

```bash
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 账户来获取更高的镜像拉取速率。

1. **完成基础配置**

请确保您已经完成了 **方式一** 中的所有步骤。

2. **登录代理服务**

使用 `docker login` 命令并输入您的 Docker Hub 用户名和密码。

```bash
docker login your-domain.com
```

3. **同步认证信息**

登录成功后,需要手动编辑 `~/.docker/config.json` 文件,将您刚刚为 `your-domain.com` 生成的 `auth` 信息,复制一份给 `https://index.docker.io/v1/`。

修改前:
```json
{
"auths": {
"your-domain.com": {
"auth": "aBcDeFgHiJkLmNoPqRsTuVwXyZ..."
}
}
}
```

修改后:
```json
{
"auths": {
"your-domain.com": {
"auth": "aBcDeFgHiJkLmNoPqRsTuVwXyZ..."
},
"https://index.docker.io/v1/": {
"auth": "aBcDeFgHiJkLmNoPqRsTuVwXyZ..."
}
}
}
```
保存文件后,您的 `docker pull` 请求就会以认证用户的方式发送,从而享受更高的速率限制。

## 开发

> [!NOTE]
> 详细的技术背景、系统架构和实现流程,请参阅 [**技术架构与原理文档**](docs/ARCHITECTURE.md)。

1. **克隆仓库**
```bash
git clone https://github.com/harrisonwang/wharf.git
cd wharf
```

2. **修改配置文件**
打开 `config/default.toml.example`,复制为 `config/default.toml`,然后修改配置。开发调试时建议本地跑 HTTP(8080),通过 Tunnel 对外提供 HTTPS 域名。

```bash
cp config/default.toml.example config/default.toml
```

然后编辑 `config/default.toml`:

```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]` 字段,可使用占位路径。

3. **运行项目**
现在,可以直接用 `cargo` 运行项目。
```bash
cargo run
```
服务将启动并监听在 `http://0.0.0.0:8080`。

4. **通过 Tunnel 暴露公网域名(便于本地联调)**
在另一个终端启动隧道,将公网请求转发到本地 `8080`。以下命令为示例,具体参数以各服务商文档为准。

```bash
# ngrok
ngrok http 8080

# tunnl.gg(示例)
ssh -N -R :80:127.0.0.1:8080

# 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`

5. **验证链路**
```bash
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` 头影响。

6. **构建发布版本**
```bash
cargo build --release
```

## 许可证

本项目采用 MIT 许可证,查看 [LICENSE](LICENSE) 了解更多信息。