代理:sing-box 的 Docker 单 VPS 部署流程
使用 Docker Compose 部署 VLESS Reality,并通过 CDN 分发 Clash YAML 订阅的完整流程。
文章目录
本文记录一套适合个人长期维护的 sing-box 部署方案:使用单台 VPS 和 Docker Compose 部署 VLESS Reality,客户端使用 Clash Verge Rev 或 Mihomo,YAML 订阅文件放在 CDN,不额外部署 Caddy。
一、服务器准备
推荐配置:
| 项目 | 推荐 |
|---|---|
| 系统 | Debian 12 |
| 内存 | 1 GB 以上 |
| CPU | 1 核即可 |
| 地区 | 日本、新加坡或香港 |
更新系统:
apt update && apt upgrade -y
安装基础工具:
apt install -y curl vim git ufw
二、安装 Docker
安装 Docker:
curl -fsSL https://get.docker.com | bash
安装 Docker Compose 插件:
apt install -y docker-compose-plugin
检查版本:
docker --version
docker compose version
三、创建项目目录
mkdir -p /opt/sing-box/config
mkdir -p /opt/sing-box/data
cd /opt/sing-box
最终目录结构:
/opt/sing-box
├── docker-compose.yml
├── config/
│ └── config.json
└── data/
四、生成 UUID
docker run --rm ghcr.io/sagernet/sing-box:v1.13.12 generate uuid
保存命令输出,例如:
12345678-1234-1234-1234-123456789abc
五、生成 Reality 密钥
docker run --rm ghcr.io/sagernet/sing-box:v1.13.12 generate reality-keypair
命令会输出:
PrivateKey: xxxxxxxxx
PublicKey: xxxxxxxxx
妥善保存 PrivateKey 和 PublicKey,不要公开服务端的 PrivateKey。
shortId:作用与配置规则
shortId 是 Reality 握手时校验的短标识。客户端携带的标识必须被服务端接受,才能通过这项握手校验;它与 Reality 密钥、VLESS UUID 一起使用,不能代替 UUID 身份验证。它不控制网站分流,也不对应某个端口或域名。
生成一个随机的 8 字节标识(输出 16 个十六进制字符):
openssl rand -hex 8
例如输出 a1b2c3d4e5f6070。这是演示值,实际部署请使用自己生成的值,分别填入第七步和第十一步的配置:
| 位置 | 字段及示例 | 规则 |
|---|---|---|
| sing-box 服务端 | tls.reality.short_id: ["a1b2c3d4e5f6070"] | 数组,可接受多个标识 |
| Mihomo / Clash 客户端 | reality-opts.short-id: "a1b2c3d4e5f6070" | 单个字符串,选服务端列表中的一个值 |
| sing-box 客户端 | tls.reality.short_id: "a1b2c3d4e5f6070" | 单个字符串,不是数组 |
- 只能使用十六进制字符
0–9、a–f或A–F,不加0x前缀、空格或连字符。建议统一使用小写。 - 非空值长度必须为偶数:2、4、6、8、10、12、14 或 16 个字符,最多 8 字节。建议直接生成 16 个字符;17 位、奇数位或含
g的值均无效。 - sing-box v1.13.12 将不足 8 字节的值在末尾补零后匹配,因此
ab与ab00会得到相同标识。配置时直接复制完整值,避免歧义。 - 该版本允许空字符串作为全零标识,但双方必须对应;个人部署建议使用随机非空值,并将 YAML 值加引号,避免纯数字值被当成数字。
- 多个客户端可以共用一个 shortId;服务端的 shortId 列表与
users中的 UUID 没有逐项绑定关系。需要区分或撤销用户访问时,应分别配置 UUID。
轮换时,先把新值加入服务端列表,例如 "short_id": ["a1b2c3d4e5f6070", "1122334455667788"],检查配置并重启服务端,再更新订阅并让客户端刷新。确认客户端均已切换后,删除旧值并再次检查、重启;旧值将无法通过后续的新连接校验。
格式限制依据本文使用的 sing-box v1.13.12 服务端实现和客户端实现;Mihomo 字段名称见 VLESS 官方文档。
六、创建 Docker Compose 配置
编辑配置文件:
vim /opt/sing-box/docker-compose.yml
写入:
services:
sing-box:
image: ghcr.io/sagernet/sing-box:v1.13.12
container_name: sing-box
restart: unless-stopped
network_mode: host
volumes:
- ./config:/etc/sing-box
- ./data:/var/lib/sing-box
command: -D /var/lib/sing-box -C /etc/sing-box run
ulimits:
nofile:
soft: 65535
hard: 65535
七、创建 sing-box 配置
编辑配置文件:
vim /opt/sing-box/config/config.json
写入以下配置:
{
"log": {
"level": "info",
"timestamp": true
},
"inbounds": [
{
"type": "vless",
"tag": "vless-reality-in",
"listen": "::",
"listen_port": 8443,
"users": [
{
"uuid": "你的UUID",
"flow": "xtls-rprx-vision"
}
],
"tls": {
"enabled": true,
"server_name": "www.cloudflare.com",
"reality": {
"enabled": true,
"handshake": {
"server": "www.cloudflare.com",
"server_port": 443
},
"private_key": "你的PrivateKey",
"short_id": [
"a1b2c3d4e5f6070"
]
}
}
}
],
"outbounds": [
{
"type": "direct",
"tag": "direct"
}
]
}
替换以下内容:
| 字段 | 替换内容 |
|---|---|
你的UUID | 第四步生成的 UUID |
你的PrivateKey | 第五步生成的 PrivateKey |
a1b2c3d4e5f6070 | 自己生成的 shortId;客户端使用相同值 |
八、检查配置
cd /opt/sing-box
docker compose run --rm sing-box check -C /etc/sing-box
如果输出以下内容,说明配置有效:
configuration ok
九、启动 sing-box
cd /opt/sing-box
docker compose up -d
查看容器状态:
docker ps
实时查看日志:
docker logs -f sing-box
十、配置防火墙
ufw allow 22/tcp
ufw allow 8443/tcp
ufw enable
检查规则:
ufw status
启用 UFW 前,应确认 SSH 实际使用的端口已经放行,避免失去服务器连接。
十一、创建 Clash YAML
在本地创建订阅文件:
mkdir -p ~/sub
vim ~/sub/clash.yaml
写入:
proxies:
- name: vless-reality
type: vless
server: 你的服务器IP或域名
port: 8443
uuid: 你的UUID
network: tcp
tls: true
udp: true
flow: xtls-rprx-vision
servername: www.cloudflare.com
reality-opts:
public-key: 你的PublicKey
short-id: "a1b2c3d4e5f6070"
client-fingerprint: chrome
proxy-groups:
- name: PROXY
type: select
proxies:
- vless-reality
- DIRECT
rules:
- GEOIP,CN,DIRECT
- MATCH,PROXY
替换以下字段:
| 字段 | 内容 |
|---|---|
你的服务器IP或域名 | VPS IP 或域名 |
你的UUID | 第四步生成的 UUID |
你的PublicKey | 第五步生成的 PublicKey |
a1b2c3d4e5f6070 | 服务端 short_id 列表中的一个值 |
rules 是客户端分流规则,与 shortId 校验独立:按从上到下的顺序匹配,GEOIP,CN,DIRECT 将目标 IP 被识别为中国的连接直连,MATCH,PROXY 将其余连接交给 PROXY 策略组。使用客户端的规则模式才会按这些规则分流;选择 PROXY 组里的 DIRECT 时,该组的流量也会直连。
订阅文件中包含服务器地址、UUID 和公钥,应避免使用完全公开、可被搜索引擎索引的地址。可以为 CDN 链接增加访问控制,或使用难以猜测的文件路径。
十二、上传 YAML 到 CDN
可选择:
- Cloudflare Pages
- GitHub Pages
- 对象存储(OSS、S3 等)
最终得到类似地址:
https://sub.example.com/clash.yaml
或者:
https://example.pages.dev/clash.yaml
十三、导入客户端
在 Clash Verge Rev 或其他 Mihomo 客户端中导入订阅地址:
https://sub.example.com/clash.yaml
更新配置后,选择 PROXY 策略组中的 vless-reality 节点即可。
十四、常用维护命令
进入项目目录:
cd /opt/sing-box
启动:
docker compose up -d
停止:
docker compose down
重启:
docker compose restart
查看日志:
docker logs -f sing-box
拉取新镜像并重建容器:
docker compose pull
docker compose up -d
升级前建议阅读 sing-box 的版本变更说明,并备份 /opt/sing-box/config。
十五、开启 BBR
将配置写入 /etc/sysctl.conf:
echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf
sysctl -p
检查是否生效:
sysctl net.ipv4.tcp_congestion_control
预期输出:
net.ipv4.tcp_congestion_control = bbr
十六、最终架构
VPS
└── sing-box Docker
CDN
└── clash.yaml
客户端
└── Clash Verge Rev / Mihomo
这套方案组件较少,服务端只运行 sing-box 容器,订阅文件交给 CDN 分发,适合希望降低维护复杂度的个人部署场景。请确保使用方式符合服务器所在地、使用所在地及服务提供商的法律和条款。