使用 Docker Compose 部署 sing-box + Hysteria2
本文介绍 sing-box 的作用,并以 Hysteria2 服务端为例,给出一套可维护的 Docker Compose 部署与客户端使用方法。文中的域名、密码和路径均为示例,请替换后再使用。
一、项目地址与官方资料
开源仓库:SagerNet/sing-box
官方文档:sing-box.sagernet.org
Docker 部署文档:Docker - sing-box
Hysteria2 服务端配置:Hysteria2 Inbound
Hysteria2 客户端配置:Hysteria2 Outbound
官方图形客户端:Graphical Clients
sing-box 官方将其定义为“The universal proxy platform”,即通用代理平台。项目采用 Go 开发,主体按 GPL-3.0-or-later 发布。
二、sing-box 有什么作用
sing-box 是一个可同时充当代理服务端和客户端的网络代理核心。它通过 JSON 配置文件组合入站、出站、DNS 和路由规则,支持 Hysteria2、Shadowsocks、Trojan、VLESS、TUIC、WireGuard 等多种协议。
典型用途包括:
在自己的服务器和设备之间建立加密代理通道;
根据域名、IP、端口或规则集进行分流;
在 Android、iOS、macOS、Windows 和 Linux 上使用统一配置;
作为其他网关或代理软件的底层网络核心。
本文使用的 Hysteria2 基于 QUIC,主要承载在 UDP 上。在高延迟或存在一定丢包的网络中,它通常比传统 TCP 代理更容易保持吞吐量,但它并不能突破服务器带宽上限,也不能解决所有线路质量问题。
请仅在法律和服务条款允许的范围内使用。
三、本文部署结构
客户端
|
| Hysteria2 + TLS + UDP/8443
v
云服务器公网 IP
|
v
Docker(host 网络)
|
v
sing-box hysteria2 inbound
|
v
direct outbound -> 目标网站
使用 network_mode: host 后,容器直接监听宿主机 UDP 端口,不需要在 Compose 中编写 ports 映射。Hysteria2 是 QUIC/UDP 服务,所以防火墙必须放行 UDP,而不是只放行同端口的 TCP。
四、服务器准备
建议准备:
一台具有公网 IPv4 或 IPv6 的 Linux 服务器;
Ubuntu 22.04 或更新版本;
一个解析到服务器公网 IP 的域名,例如 hy2.example.com;
Docker Engine 与 Docker Compose Plugin;
云厂商安全组和系统防火墙均允许目标 UDP 端口。
安装 Docker
下面以 Ubuntu 为例。若服务器已经安装 Docker,可跳过这一节。
sudo apt-get update
sudo apt-get install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg
-o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" |
sudo tee /etc/apt/sources.list.d/docker.list >/dev/null
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
docker-buildx-plugin docker-compose-plugin
sudo docker version
sudo docker compose version
配置域名和防火墙
将 hy2.example.com 的 A 记录指向服务器公网 IPv4。若使用 IPv6,再添加 AAAA 记录。
使用 UFW 时可以这样放行:
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 8443/udp
sudo ufw status
80/tcp 用于 Certbot 申请和续期证书。如果服务器上已有 Nginx 或 Caddy,应改用与现有 Web 服务兼容的 ACME 验证方式。云厂商安全组也需要单独放行 8443/udp。
申请可信 TLS 证书
sudo apt-get update
sudo apt-get install -y certbot
sudo certbot certonly --standalone
-d hy2.example.com
--agree-tos
--email admin@example.com
--non-interactive
证书通常位于:
/etc/letsencrypt/live/hy2.example.com/fullchain.pem
/etc/letsencrypt/live/hy2.example.com/privkey.pem
生产环境推荐使用受信任 CA 签发的证书。自签名证书也能工作,但客户端必须安全地取得并信任该证书;不建议长期使用“跳过证书验证”。
五、创建服务端配置
创建部署目录:
sudo install -d -m 700 /opt/sing-box-hy2
cd /opt/sing-box-hy2
生成两个彼此独立的随机密码:
openssl rand -base64 32
openssl rand -base64 32
第一个作为用户认证密码,第二个作为 Salamander 混淆密码。不要把密码提交到 Git 仓库,也不要直接放进公开博客。
创建 /opt/sing-box-hy2/config.json:
{
"log": {
"level": "info",
"timestamp": true
},
"inbounds": [
{
"type": "hysteria2",
"tag": "hy2-in",
"listen": "::",
"listen_port": 8443,
"up_mbps": 100,
"down_mbps": 300,
"obfs": {
"type": "salamander",
"password": "请替换为混淆密码"
},
"users": [
{
"name": "user1",
"password": "请替换为认证密码"
}
],
"tls": {
"enabled": true,
"server_name": "hy2.example.com",
"alpn": [
"h3"
],
"certificate_path": "/etc/letsencrypt/live/hy2.example.com/fullchain.pem",
"key_path": "/etc/letsencrypt/live/hy2.example.com/privkey.pem"
}
}
],
"outbounds": [
{
"type": "direct",
"tag": "direct"
}
]
}
up_mbps 和 down_mbps 是 Hysteria2 拥塞控制使用的最大带宽参数,单位为 Mbps。应按照线路的实际可用带宽设置,不是填写得越大越好。服务端和客户端需要使用合理、匹配的带宽值。
限制配置文件权限:
sudo chmod 600 /opt/sing-box-hy2/config.json
六、创建 Docker Compose 文件
创建 /opt/sing-box-hy2/docker-compose.yml:
services:
sing-box-hy2:
image: ghcr.io/sagernet/sing-box:latest
container_name: sing-box-hy2
restart: unless-stopped
network_mode: host
volumes:
./config.json:/etc/sing-box/config.json:ro
/etc/letsencrypt:/etc/letsencrypt:ro
command: -D /var/lib/sing-box -C /etc/sing-box run
logging:
driver: json-file
options:
max-size: 10m
max-file: "3"
官方文档使用 ghcr.io/sagernet/sing-box 镜像。生产环境更稳妥的做法是先验证版本,再把 latest 改为经过测试的具体版本标签,避免上游更新后出现不兼容变化。
七、检查并启动服务
先让 sing-box 检查配置语法:
cd /opt/sing-box-hy2
sudo docker compose run --rm sing-box-hy2
-C /etc/sing-box check
确认没有错误后启动:
sudo docker compose pull
sudo docker compose up -d
sudo docker compose ps
sudo docker compose logs --tail=100 sing-box-hy2
检查 UDP 端口:
sudo ss -lunp | grep ':8443'
Hysteria2 使用 UDP,不能用浏览器、curl 或普通 TCP 端口检测来判断它是否正常。最可靠的验证方式是查看服务日志并使用配置正确的 Hysteria2 客户端实际连接。
八、客户端怎么配置
官方图形客户端包括:
Android:sing-box for Android
iOS、macOS、Apple tvOS:sing-box for Apple platforms
Windows、Linux:sing-box for Desktop
在图形客户端中新建 Hysteria2 节点时,各字段与服务端的对应关系如下:
客户端字段示例必须与服务端一致Server / 地址hy2.example.com是Port / 端口8443是Password / 认证密码服务端 users[].password是Obfs typesalamander是Obfs password服务端 obfs.password是TLS开启是Server name / SNIhy2.example.com必须匹配证书ALPNh3建议一致Allow insecure关闭生产环境应关闭
保存节点后,选择该配置并开启系统代理或 TUN/VPN 模式。只创建节点但没有启用系统代理或 VPN 模式时,系统流量不会自动经过该节点。
使用 sing-box JSON 客户端
下面是一份适合命令行或桌面端导入的最小客户端示例。它在本机 127.0.0.1:2080 提供 HTTP/SOCKS 混合代理:
{
"log": {
"level": "info",
"timestamp": true
},
"inbounds": [
{
"type": "mixed",
"tag": "mixed-in",
"listen": "127.0.0.1",
"listen_port": 2080
}
],
"outbounds": [
{
"type": "hysteria2",
"tag": "hy2-out",
"server": "hy2.example.com",
"server_port": 8443,
"up_mbps": 20,
"down_mbps": 100,
"obfs": {
"type": "salamander",
"password": "请替换为混淆密码"
},
"password": "请替换为认证密码",
"tls": {
"enabled": true,
"server_name": "hy2.example.com",
"alpn": [
"h3"
]
}
}
],
"route": {
"final": "hy2-out",
"auto_detect_interface": true
}
}
启动客户端核心后,把浏览器或操作系统代理设置为:
地址:127.0.0.1
端口:2080
类型:HTTP 或 SOCKS5
如果服务端使用自签名证书
更安全的做法是通过可信渠道把服务端的公开证书 cert.pem 传给客户端,并在客户端 TLS 配置中加入:
{
"enabled": true,
"server_name": "证书中的域名",
"certificate_path": "/客户端上的安全路径/cert.pem",
"alpn": [
"h3"
]
}
insecure: true 会接受任意服务器证书,容易受到中间人攻击,只适合短时间排障,不应作为正式配置。
九、日常维护
查看状态和日志:
cd /opt/sing-box-hy2
sudo docker compose ps
sudo docker compose logs --tail=200 sing-box-hy2
sudo docker stats sing-box-hy2
修改配置后,先检查再重启:
sudo docker compose run --rm sing-box-hy2
-C /etc/sing-box check
sudo docker compose restart sing-box-hy2
更新镜像:
sudo docker compose pull
sudo docker compose up -d
sudo docker image prune
十、常见问题
客户端一直超时
重点检查云安全组和 UFW 是否放行 8443/udp,以及服务端是否真的监听 UDP 端口。只开放 8443/tcp 没有作用。
出现证书验证失败
检查客户端 server_name 是否与证书域名一致、域名是否解析到正确 IP、证书是否过期。自签名证书还需要客户端显式信任对应证书。
日志提示认证失败
客户端的认证密码必须与服务端 users[].password 完全一致。用户名只是服务端用于区分用户,sing-box 的 Hysteria2 认证核心字段是密码。
开启 Salamander 后无法连接
客户端和服务端的 obfs.type、obfs.password 必须同时一致。排查时可以在两端同时暂时移除 obfs,不能只改一端。
节点连接成功但应用没有流量
确认图形客户端已启用系统代理或 TUN/VPN 模式。若只使用本地 mixed 入站,还需要把应用代理指向 127.0.0.1:2080。
总结
sing-box 是一个通用代理平台,Hysteria2 只是它支持的协议之一。部署成功的关键点并不多:服务端开放正确的 UDP 端口、两端认证与混淆参数一致、TLS 域名匹配,并在客户端真正启用系统代理或 TUN/VPN 模式。生产环境还应固定经过验证的镜像版本、限制日志大小、保护配置权限,并建立证书续期后的重启机制。