重要声明:本文仅用于测试体验,不是生产环境部署指南。DeepSeek Harness(
dsh)尚处于测试 / developer preview 阶段,接口、配置、插件行为、CLI 参数和 Web UI 都可能随时发生破坏性变更。请勿直接用这套方案承载生产业务、敏感数据或长期公网服务。
DeepSeek Harness(dsh)是 DeepSeek AI 开源的 Agent Harness,采用“一切皆插件”的架构。本文目标:在一台云服务器或内网机器上部署 DeepSeek Harness Web UI,并通过 Nginx 或 Caddy 反向代理 + Basic Auth,实现域名或纯 IP 访问;HTTPS 按测试条件可选。
注意:dsh 默认只监听 127.0.0.1,不支持直接绑定 0.0.0.0。因此不要试图把它的端口直接暴露到公网或内网其他机器。正确做法是让 Nginx 或 Caddy 监听 80/443,再反向代理到本机 127.0.0.1:3080。
本文中 Nginx 和 Caddy 是同级反向代理选项,二选一;Certbot 仅用于 Nginx,Caddy 不需要 Certbot。
1. 最终架构
浏览器 / Web UI
|
| 方案A: Nginx + Basic Auth + Certbot HTTPS
| 方案B: Caddy + Basic Auth + 自动 HTTPS / 纯 IP HTTP
v
Nginx / Caddy :80 / :443
|
| HTTP + WebSocket
v
dsh 127.0.0.1:3080
|
v
插件、模型、工具、后端依赖
关键点:
dsh只监听本机,不直接暴露公网或内网。- Nginx / Caddy 负责反向代理、Basic Auth 和 WebSocket。
- 纯 IP 访问时,
--trusted-host填实际访问 IP,例如123.123.123.123或192.168.1.10。 - 域名访问时,
--trusted-host填实际域名,例如dsh.example.com。 - 云安全组 / 防火墙只开放
22、80、443,不要开放3080。 - 反向代理层二选一:
- 方案 A:Nginx,HTTPS 用 Certbot 申请。
- 方案 B:Caddy,HTTPS 由 Caddy 自动处理,不使用 Certbot。
2. 准备云服务器
以 Debian 13 为例。安全组 / 防火墙建议:
| 端口 | 用途 | 来源 |
|---|---|---|
| 22 | SSH | 仅你的固定 IP |
| 80 | HTTP | 公网 |
| 443 | HTTPS | 公网 |
| 3080 | dsh | 不要开放 |
3. 安装 Node.js
DeepSeek Harness 通过 npm 分发,先安装 Node.js。
curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
sudo apt install -y nodejs
node -v
npm -v
4. 首次本地启动 dsh
先不要配外界访问,先确认 dsh 本身能跑起来。
npx -y @deepseek-ai/dsh --profile web --no-open --port 3080 --trusted-host dsh.example.com
参数以实际 --help 为准。服务器上没有桌面环境,必须加 --no-open,否则它可能尝试打开浏览器。
首次运行会下载 npm 包,稍等片刻。开始运行后会输出一个带 access token 的地址。
启动后检查监听地址:
sudo ss -lntp | grep 3080
你应该看到类似:
LISTEN 0 511 127.0.0.1:3080 0.0.0.0:*
本地验证:
curl -I -H "Host: dsh.example.com" http://127.0.0.1:3080
能返回 HTTP 响应即可。
5. 用 systemd 守护 dsh
说明:以下使用 root 运行,仅用于测试体验。生产环境不建议以 root 运行 Web 服务。若长期使用,请创建专用用户并限制权限。
sudo npm install -g @deepseek-ai/dsh
确认可执行文件路径:
command -v dsh
通常为 /usr/bin/dsh。用实际路径替换 ExecStart 中的命令。
创建服务文件:
sudo tee /etc/systemd/system/dsh.service > /dev/null <<'EOF'
[Unit]
Description=DeepSeek Harness Web UI
After=network.target
[Service]
Type=simple
User=root
Group=root
WorkingDirectory=/root
# 若为纯 IP 方案,请把 --trusted-host 改为实际访问 IP
ExecStart=/usr/bin/dsh --profile web --no-open --port 3080 --trusted-host dsh.example.com
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
启动并设置开机自启:
sudo systemctl daemon-reload
sudo systemctl enable --now dsh
查看日志并获取 access token:
sudo systemctl status dsh
日志中会输出带 access token 的地址。若未看到,可尝试:
sudo journalctl -u dsh --no-pager | grep -i token
6. 安装并配置反向代理与 Basic Auth:Nginx 或 Caddy 二选一
由于 dsh 不支持 --bind 0.0.0.0,需要安装 Nginx 或 Caddy 作为反向代理,并配置 Basic Auth 与 WebSocket。两者功能同级,选一个即可。
- 选 Nginx:继续看 6.1,后续 HTTPS 用 Certbot,见 7.1。
- 选 Caddy:直接看 6.2,Caddy 自动处理 HTTPS,不需要 Certbot,见 7.2。
6.1 方案 A:Nginx + Basic Auth + 反向代理 + WebSocket
6.1.1 安装 Nginx 与 Basic Auth 工具
sudo apt install -y nginx apache2-utils
创建 Basic Auth 用户:
sudo htpasswd -B -C 10 -c /etc/nginx/.htpasswd admin
注意:-c 会覆盖已有文件。第一次创建可用;后续添加用户不要加 -c,例如:
sudo htpasswd -B -C 10 /etc/nginx/.htpasswd 新用户名
查看文件:
cat /etc/nginx/.htpasswd
6.1.2 创建仅监听 80 的站点配置
创建站点配置:
sudo tee /etc/nginx/sites-available/dsh.conf > /dev/null <<'EOF'
server {
listen 80;
listen [::]:80;
server_name dsh.example.com;
location ^~ /.well-known/acme-challenge/ {
auth_basic off;
root /var/www/html;
default_type text/plain;
}
auth_basic "DeepSeek Harness";
auth_basic_user_file /etc/nginx/.htpasswd;
client_max_body_size 100m;
location / {
proxy_pass http://127.0.0.1:3080;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_buffering off;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}
EOF
6.1.3 配置 WebSocket 升级 map
把 map 放到 http 上下文,例如新建 /etc/nginx/conf.d/ws-upgrade.conf:
sudo tee /etc/nginx/conf.d/ws-upgrade.conf > /dev/null <<'EOF'
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
EOF
6.1.4 启用站点并验证 HTTP
启用站点:
sudo rm -f /etc/nginx/sites-enabled/default
sudo ln -sf /etc/nginx/sites-available/dsh.conf /etc/nginx/sites-enabled/dsh.conf
sudo nginx -t && sudo systemctl reload nginx
此时可以先通过 HTTP 验证:
curl -I -H "Host: dsh.example.com" http://127.0.0.1
也可以用浏览器访问 http://dsh.example.com,应弹出 Basic Auth 登录框。输入刚才的 admin 和密码。若显示需要 access token,则复制上文所说的带 access token 的地址,并将 127.0.0.1 改为 dsh.example.com。
6.1.5 验证 WebSocket
浏览器打开开发者工具 → Network → WS,查看是否有 WebSocket 连接成功。
若返回 101 Switching Protocols 或类似升级响应,说明 WebSocket 路径基本正常。反向代理层则需通过浏览器实际验证。
Nginx 的 HTTPS 配置见 7.1。
6.2 方案 B:Caddy + Basic Auth + 反向代理 + WebSocket
Caddy 对 WebSocket 支持较好,通常不需要手动设置 Upgrade / Connection 头。Caddy 还会自动处理 HTTPS,因此域名方案会自动申请证书;纯 IP 方案见下方说明。
6.2.1 安装 Caddy 并生成 Basic Auth 哈希
按 Caddy 官方文档或系统包管理器安装 Caddy。以下假设你已安装好 caddy 命令。
生成 bcrypt 哈希:
caddy hash-password
按提示输入密码,得到类似 $2a$14$... 的哈希,记下来,稍后填入 Caddyfile。
Caddy 不需要 htpasswd,也不需要 Certbot。
6.2.2 域名方案 Caddyfile
dsh.example.com {
basic_auth {
admin $2a$14$你的bcrypt哈希
}
reverse_proxy 127.0.0.1:3080 {
header_up Host {host}
header_up X-Forwarded-Proto {scheme}
flush_interval -1
}
}
把 $2a$14$你的bcrypt哈希 替换为 6.2.1 中 caddy hash-password 生成的哈希。
Caddy 会自动申请证书并处理 WebSocket。此时 dsh 的 --trusted-host 仍然要设置为 dsh.example.com。
6.2.3 纯 IP 方案 Caddyfile(仅测试)
Caddy 不会为纯 IP 自动申请公网证书。可选:
http://123.123.123.123 {
basic_auth {
admin $2a$14$你的bcrypt哈希
}
reverse_proxy 127.0.0.1:3080 {
header_up Host {host}
header_up X-Forwarded-Proto {scheme}
flush_interval -1
}
}
或使用内部 CA 自签(浏览器会警告):
https://123.123.123.123 {
tls internal
basic_auth {
admin $2a$14$你的bcrypt哈希
}
reverse_proxy 127.0.0.1:3080 {
header_up Host {host}
header_up X-Forwarded-Proto {scheme}
flush_interval -1
}
}
此时 dsh 的 --trusted-host 必须设置为 123.123.123.123。
Caddy 不需要 Certbot,具体说明见 7.2。
7. HTTPS 与证书
7.1 Nginx 用户:Certbot 申请 HTTPS
前提:
- 已完成 6.1,Nginx 已监听 80,且
server_name为实际域名,例如dsh.example.com。 - 域名 A 记录已解析到服务器公网 IP。
- 安全组已开放
80和443。
先安装 Certbot 及 Nginx 插件:
sudo apt install -y certbot python3-certbot-nginx
运行 Certbot:
sudo certbot --nginx -d dsh.example.com
首次运行会要求输入邮箱、同意条款,并询问是否将 HTTP 重定向到 HTTPS。Certbot 会自动修改 Nginx 配置、申请证书、添加 443 监听和跳转。
如需非交互方式:
sudo certbot --nginx -d dsh.example.com --non-interactive --agree-tos -m you@example.com --redirect
验证自动续期:
sudo certbot renew --dry-run
现在用浏览器访问:
https://dsh.example.com
应该会弹出 Basic Auth 登录框。输入刚才的 admin 和密码。
若显示需要 access token,则复制上文所说的带 access token 的地址,并将 127.0.0.1 改为 dsh.example.com 即可。
7.2 Caddy 用户:无需 Certbot
Caddy 不需要 Certbot。域名场景下 Caddy 会自动申请和续期证书;纯 IP 场景下 Caddy 不会自动获得公网证书,只能用 http:// 或 tls internal 自签测试。
- 域名:使用 6.2.2 的 Caddyfile,Caddy 自动 HTTPS。
- 纯 IP:使用 6.2.3 中的
http://IP或https://IP+tls internal。 - 不要为 Caddy 安装或运行 Certbot。
dsh的--trusted-host必须与浏览器实际访问的主机一致:域名或纯 IP。
8. 总结
- 反向代理层:Nginx 或 Caddy,同级二选一。
- 如果选 Nginx:用 Certbot 申请和续期 HTTPS 证书。
- 如果选 Caddy:Caddy 自己负责反向代理和 HTTPS,不需要 Certbot。
- 纯 IP 测试时:
- Nginx 可先跑 HTTP,再按条件配证书;
- Caddy 可用
http://IP,或用https://IP+tls internal自签。
dsh始终只监听127.0.0.1:3080,由 Nginx / Caddy 反向代理。--trusted-host必须与浏览器实际访问的主机一致,例如域名或公网/内网 IP。- 云安全组 / 防火墙只开放
22、80、443,不要开放3080。