使用DeepSeek Harness进行远程服务器运维
在云服务器上部署 DeepSeek Harness 并通过远程访问让其成为服务器运维助手的完整教程。
探索未至之境:把 DeepSeek Harness 变成我的远程运维助手
本文完整记录 DeepSeek Harness 在云服务器上的部署流程:环境准备与构建、systemd 服务化、Nginx 反代与 Basic Auth 访问认证、远程访问控制,以及三次典型的「公网可访问但接口不可用」排障。重点是 Host 信任(trustedHosts)、浏览器兼容性(randomUUID)与回环信任(loopback fence)的逐层打通,文中所有命令均亲测通过。
一、背景与方案选择
1、为什么要在博客上部署 DeepSeek Harness
2026 年 8 月 13 日,DeepSeek Harness 正式发布,正如它的宣传语所说——探索未至之境——上手一试,确实很强:Agent 会话、评测任务管理一应俱全,本地跑起来只能「自己用」,总感觉有点浪费。
于是我就琢磨开了:既然博客就搭在云服务器上,那能不能把 DeepSeek Harness 也部署上去,让它成为我的远程「运维助手」?人在哪儿,助手就在哪儿,浏览器一开就能用。说干就干,这么做的好处其实很实在:
- 家里、公司、出差路上,只要有浏览器就能访问,不用背着开发机跑;
- Agent 长任务(评测、批量跑实验)可以 7×24 小时挂在服务器上跑,不占本地资源;
- 多台设备共享同一个会话历史(
session.history),工作记录不丢。
2、踩坑记录:三次典型排障
从「公网能打开页面」到「特权 API 全部可用」,一共踩了三个典型的坑。这三个坑的本质是一条信任链的逐层打通:第一层是 Host 信任(trustedHosts),第二层是浏览器兼容性(randomUUID),第三层是回环信任(loopback fence)。排障时按这个思路逐层排查,能少走很多弯路。每个坑按下述结构整理,方便复现排查。
问题① 外部可访问但 /api 返回 403 → 添加 --trusted-host
-
现象:公网访问 DeepSeek Harness Web UI 页面正常(HTML 加载正常),但页面里的
/api相关请求全部返回 403,功能不可用。浏览器开发者工具(Network 标签)可见大量/api/*请求返回 403。 -
根因:DeepSeek Harness 的 trustedHosts(Host 信任)机制会校验请求 Host。公网 Host 是
服务器公网地址:对外端口,不在默认信任列表里,非特权 API 方法被拒绝。 -
修复:
-
在 systemd 服务
ExecStart中追加两个--trusted-host(带端口与不带端口双形态):Terminal window dsh web --trusted-host 服务器公网地址:对外端口 --trusted-host 服务器公网地址 -
同时
location /里必须用proxy_set_header Host $http_host;保留端口,不能用$host(会丢弃端口)。因为后端 browser-trust fence 校验 Host 与 Origin 一致性,浏览器 Origin 带端口(服务器公网地址:对外端口),若 Host 无端口仍会 403。
proxy_set_header Host $http_host; # ✅ 保留端口# proxy_set_header Host $host; # ❌ $host 不含端口,会丢端口- 改完 service 文件后
systemctl daemon-reload && systemctl restart dsh-web;改完 nginx 配置后nginx -t && nginx -s reload。
-
-
验证:非特权 API 请求恢复 200,页面基础功能可用。
问题② 控制台报 crypto.randomUUID is not a function → sub_filter 注入 polyfill
-
现象:前端控制台(Console)报
Uncaught TypeError: crypto.randomUUID is not a function,页面部分功能(依赖随机 UUID 的逻辑)不可用。 -
根因:部分浏览器环境未实现
crypto.randomUUID,调用即抛 TypeError。 -
修复:用 nginx
sub_filter在返回的 HTML</head>前注入一个基于crypto.getRandomValues的 UUID v4 polyfill(完整代码见第四节location /):proxy_set_header Accept-Encoding ""; # 必须:让后端返回未压缩 HTML,sub_filter 才能匹配sub_filter '</head>' '</head><script>(function(){...})();</script>';sub_filter_once on;proxy_set_header Accept-Encoding "";是必须的:否则后端返回 gzip 压缩的 HTML,sub_filter无法匹配到</head>,注入不生效;sub_filter_once on;:只在第一个</head>处注入一次;- 不要显式声明
sub_filter_types text/html:会与全局 mime.types 重复定义,产生nginx -t警告。
-
验证:polyfill 注入生效,页面无 JS 报错,Console 干净。
问题③ /api/settings.describe 等特权方法仍返回 403 → location /api 伪造回环 Host/Origin
-
现象:已配置
--trusted-host后,非特权 API 已恢复 200,但settings.describe、settings.update、credentials.set等特权方法仍返回 403,即使带认证凭据访问也一样。 -
根因:DeepSeek Harness 将
settings.describe、settings.update、credentials.set等敏感 API 注册在 loopback 信任通道(authority: 'loopback',见packages/client/connection/src/rpc-host.ts)上,强制要求请求来自回环地址(loopback fence),这是 DeepSeek Harness 的故意安全设计——--trusted-host只是防止 DNS-rebinding 的 Host 校验,并非认证层,因此无法放行特权方法。要让公网请求通过,必须让后端「以为」请求来自回环。 -
修复:新增独立的
location /api,转发时伪造回环 Host/Origin:location /api {proxy_pass http://127.0.0.1:后端端口;# 伪造回环 Host/Origin,使特权方法通过 DeepSeek Harness 回环 fenceproxy_set_header Host 127.0.0.1:后端端口;proxy_set_header Origin http://127.0.0.1:后端端口;# ... 其余反代头与 WebSocket 配置同 location /}Origin必须硬编码为http://127.0.0.1:后端端口与Host保持一致;若用$http_origin携带公网原始 Origin,仍会因与 Host 不一致而 403;/api/events.mux、/api/events.host等 WebSocket 端点也走本 location,loopback 为最高信任,升级握手仍能通过 fence;- 权衡:这一步等于绕过了 DeepSeek Harness 内置的回环保护,真实的访问认证完全由 server 级 Basic Auth 承担——即「Basic Auth 是替代认证方案」。安全权衡必须明确记录:一旦凭据泄露,任何通过认证的请求都可调用特权方法,凭据强度就是最后一道防线。
-
验证:浏览器访问
settings.describe、session.history等请求全部返回 200,页面完整功能可用。
排障时按「信任链」逐层排查:先看 Host 信任(trustedHosts),再看浏览器兼容性(randomUUID),最后看回环信任(loopback fence)。每层打通后验证一次,能少走很多弯路。
3、方案选择:Nginx 反代 + Basic Auth
公网 IP + 对外端口 + Basic Auth,由 Nginx 反代到仅监听回环地址的后端 DeepSeek Harness 的 web 服务。
整体架构如下:
浏览器 ──► Nginx(服务器公网地址:对外端口) ──反代──► DeepSeek Harness web(127.0.0.1:后端端口) │ │ └── Basic Auth └── --trusted-host方案要点:
- 对内:DeepSeek Harness 的 web 服务默认只监听
127.0.0.1:后端端口(有意不支持--host 0.0.0.0),后端不直接暴露网卡,对外统一交给 Nginx,这个设计其实更安全; - 对外:Nginx 监听
对外端口,叠加 Basic Auth 做访问认证;
二、环境准备
1、克隆官方仓库并固定 commit
克隆 DeepSeek Harness 官方仓库,并固定到一个已知正常的提交,避免上游漂移导致构建问题:
# 克隆自 deepseek-harness 官方仓库,固定提交git clone https://github.com/deepseek-ai/deepseek-harness.git 部署目录/deepseek-harnesscd 部署目录/deepseek-harnessgit checkout 47f943859b # Merge pull request #2519 from deepseek-harness/feat/npm-public固定 commit 是个好习惯。仓库主分支每天都在变,今天能构建、下周可能就挂了。锁定一个验证过的提交,后续升级再手动解锁,可控性高很多。
2、Node 与 pnpm 工具链
仓库根目录 package.json 声明了 "packageManager": "pnpm@11.7.0",而系统预装的 pnpm 是 10.9.0。执行 pnpm install 时 pnpm 检测到版本与声明不符,会触发「自动切换到声明版本」的流程,但该流程依赖 corepack,而这个环境里 corepack 不可用,于是安装流程直接卡死。
解法:直接把全局 pnpm 升级到仓库声明的版本(旧版备份保留,可随时回退):
# 1) 升级全局 pnpm 至 11.7.0(旧版 10.9.0 已备份为 pnpm.bak-10.9.0,未删除,可随时回退)npm install -g pnpm@11.7.0pnpm -v # 输出 v11.7.0 ✅
# 2) registry 切换为 npmmirror 国内镜像(加速依赖下载)npm config set registry https://registry.npmmirror.com/npm config get registry # 输出 https://registry.npmmirror.com/ ✅升级前把旧版 pnpm 二进制备份一份(改名保留即可,别删),万一新版本有问题还能秒回退。真出问题的时候,你会发现这个备份有多香。
3、依赖安装与构建(小内存服务器务必限制堆内存)
cd 部署目录/deepseek-harnesspnpm install # 使用 pnpm-lock.yaml 锁定版本,安装成功
# 构建:服务器内存紧张,必须限制 Node 堆内存,避免 OOMNODE_OPTIONS="--max-old-space-size=2048" pnpm run buildbuild 会执行 host + client 两套 tsc -b、tsdown 打包以及前端 Vite 构建,全是内存密集型的 Node 进程,对内存非常敏感。直接裸跑大概率看到 FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory,严重时系统 OOM Killer 直接杀进程。若仍报内存不足,可以降到 --max-old-space-size=1536(代价是构建时间变长),不建议超过 2048,不然容易把整台机器 OOM。
三、systemd 服务化
用 systemd 托管 DeepSeek Harness 的 web 进程,支持开机自启与异常自动拉起,比裸跑 nohup 省心。
1、服务文件:dsh-web.service
在 systemd 服务目录(/etc/systemd/system/ 是 systemd 服务的标准存放位置)创建 dsh-web.service:
[Unit]Description=DeepSeek Harness Web UIAfter=network.target
[Service]Type=simpleWorkingDirectory=部署目录/deepseek-harnessEnvironment=NODE_OPTIONS=--max-old-space-size=2048# 同时信任带端口与无端口两种 Host 形态:# - nginx 的 $host 变量不含端口,实际转发 Host 为 服务器公网地址# - 浏览器/直连可能携带 Host: 服务器公网地址:对外端口ExecStart=pnpm dsh web --trusted-host 服务器公网地址:对外端口 --trusted-host 服务器公网地址Restart=on-failureRestartSec=5User=root# 日志追加写入 /var/log/dsh-web.logStandardOutput=append:/var/log/dsh-web.logStandardError=append:/var/log/dsh-web.log
[Install]WantedBy=multi-user.target加载并启动:
systemctl daemon-reloadsystemctl enable dsh-web # 开机自启systemctl start dsh-websystemctl status dsh-web # active (running) ✅2、关键点说明
- 监听地址:DeepSeek Harness 的 web 服务默认只监听
127.0.0.1:后端端口(有意不支持--host 0.0.0.0),对外统一交给 Nginx 反代,这个设计其实更安全——后端不直接暴露网卡。 --trusted-host参数(解决/api403):同时传入带端口(服务器公网地址:对外端口)与不带端口(服务器公网地址)两种形态,确保 nginx 的$host转发头与浏览器直连 Host 都能通过 DeepSeek Harness 的 Host 信任校验(trustedHosts),避免非特权 API 因 Host 不符返回 403。具体原理见第一节「2、踩坑记录」问题①。- 开机自启:
systemctl enable dsh-web后状态为enabled。
改完 service 文件记得 daemon-reload!改完记得 daemon-reload!改完记得 daemon-reload!这个忘了,改十遍配置都不会生效。
四、Nginx 反代配置
配置文件:dsh.conf,放在 Nginx 站点配置目录下(即 Nginx 会 include 进来的站点配置目录,比如 /etc/nginx/conf.d/ 这类标准位置)。
1、对外端口块(核心对外入口)
server { listen 对外端口; server_name _;
# DeepSeek Harness 应用访问日志(通用日志目录,可自行调整) access_log /var/log/nginx/dsh-access.log; error_log /var/log/nginx/dsh-error.log;
# Basic Auth 访问认证(仅对外入口端口生效,后端监听地址不受影响) # 注意: 密码文件必须放在 nginx worker 可读的路径下 #(Nginx 站点配置目录权限通常是 700 root,nginx worker 进程读不到) auth_basic "DeepSeek Harness Restricted Access"; auth_basic_user_file 部署目录/dsh-auth/dsh-htpasswd;
# DeepSeek Harness 可能上传文件 / Agent 任务产物,放宽请求体大小 client_max_body_size 20m;
# ---- location / :反代 + WebSocket + sub_filter 注入 polyfill ---- location / { proxy_pass http://127.0.0.1:后端端口;
# 让后端返回未压缩的 HTML,确保 sub_filter 能注入 polyfill proxy_set_header Accept-Encoding "";
# 兼容部分浏览器对 crypto.randomUUID 的支持差异 # (部分环境未实现 crypto.randomUUID,改用 getRandomValues 模拟) sub_filter '</head>' '</head><script>(function(){try{if(typeof crypto!=="undefined"&&crypto&&!crypto.randomUUID){crypto.randomUUID=(function(){function b(a){return a.toString(16).padStart(2,"0")}return function(){var c=new Uint8Array(16);crypto.getRandomValues(c);c[6]=(c[6]&0x0f)|0x40;c[8]=(c[8]&0x3f)|0x80;var h="";for(var i=0;i<16;i++){h+=b(c[i]);if(i===3||i===5||i===7||i===9){h+="-"}}return h}})()}}catch(e){}})();</script>'; sub_filter_once on;
# 必须用 $http_host(保留端口),不能用 $host(会丢弃端口)。 # 后端 DeepSeek Harness 的 browser-trust fence 校验 Host 与 Origin 一致性, # 浏览器 Origin 带端口(服务器公网地址:对外端口),若 Host 无端口会 403。 proxy_set_header Host $http_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;
# WebSocket 支持(DeepSeek Harness 前端实时通信/事件推送) proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";
# 长连接/超时设置(Agent 任务长时运行,务必给足) proxy_read_timeout 300s; proxy_send_timeout 300s; proxy_connect_timeout 30s; }
# ---- location /api :伪造回环 Host/Origin(特权方法信任)---- location /api { proxy_pass http://127.0.0.1:后端端口;
# 伪造回环 Host/Origin,使特权方法通过 DeepSeek Harness 回环 fence proxy_set_header Host 127.0.0.1:后端端口; proxy_set_header Origin http://127.0.0.1:后端端口; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# WebSocket 支持(/api/events.* 升级握手) proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";
proxy_read_timeout 300s; proxy_send_timeout 300s; proxy_connect_timeout 30s; }}2、Basic Auth 凭据
- 账号:
admin - 密码:
you_passwd(占位,部署时务必替换为自设的强密码,不要沿用任何示例密码) - 密码文件:
dsh-htpasswd,放在「Nginx worker 可读的目录」下(如部署目录/dsh-auth/dsh-htpasswd)
生成密码文件:
mkdir -p 部署目录/dsh-auth# 生成 Basic Auth 密码文件(账号 admin,密码 you_passwd,htpasswd 加密格式)htpasswd -bc 部署目录/dsh-auth/dsh-htpasswd admin you_passwd# 调整属主与权限:root:nginx,nginx worker 可读chown root:nginx 部署目录/dsh-auth/dsh-htpasswdchmod 640 部署目录/dsh-auth/dsh-htpasswd
ls -l 部署目录/dsh-auth/dsh-htpasswd# 期望:-rw-r----- root nginx dsh-htpasswd(nginx worker 可读 ✅)密码文件路径是第一个坑:dsh-htpasswd 必须放在 nginx worker 可读的目录下,不能放在 Nginx 站点配置目录里。因为站点配置目录权限通常是 700 root,nginx worker 进程(以 nginx 用户运行)读不到,会导致所有请求直接 500,Nginx 错误日志里会看到 open() "...dsh-htpasswd" failed (13: Permission denied)。
3、location /api 为什么要伪造回环 Host/Origin(原理与权衡,务必理解)
- DeepSeek Harness 有意设计了一个回环信任围栏(loopback fence):
settings.describe、settings.update、credentials.set等敏感 API 注册在 loopback 信任通道(authority: 'loopback',见packages/client/connection/src/rpc-host.ts),强制要求请求来自回环地址(127.0.0.1 / localhost)。这是 DeepSeek Harness 的故意安全设计——即使--trusted-host也只是防止 DNS-rebinding 的 Host 校验,并非认证层,无法放行特权方法。 - 因此 nginx 在
location /api中把转发请求的Host与Origin伪造为127.0.0.1:后端端口,让特权方法误以为请求来自回环,从而通过 fence。 - 权衡:这一步等于绕过了 DeepSeek Harness 内置的回环保护,真实的访问认证由 server 级 Basic Auth 承担——即「Basic Auth 是替代认证方案」。
- 注意
/api/events.mux、/api/events.host等 WebSocket 端点也走本 location,升级握手依然能通过 fence。 - Origin 必须硬编码为
http://127.0.0.1:后端端口与 Host 保持一致;若用$http_origin携带公网原始 Origin,反而会 403。
这一步绕过了 DeepSeek Harness 内置的回环保护,属于安全权衡手段。仅建议在受控环境使用,实际认证完全依赖 Basic Auth。一旦放开,任何通过认证的请求都可以调用特权方法,所以 Basic Auth 的凭据强度就是最后一道防线。
4、生效确认
nginx -t && nginx -s reload # 语法校验通过后重载改完 nginx 配置一定要先 nginx -t 再 reload!语法错了直接全站 502 的教训,谁踩谁知道。另外,如果显式写了 sub_filter_types text/html;,nginx -t 会报「duplicate MIME type “text/html”」警告——sub_filter 默认只处理 text/html,不要显式声明这一行。
五、远程访问控制
1、浏览器访问入口
在任意设备(笔记本、手机、公司电脑)的浏览器打开:
服务器公网地址:对外端口浏览器会弹出 Basic Auth 登录框,输入:
- 账号:
admin - 密码:
you_passwd(你部署时设置的真实密码)
登录成功后进入 DeepSeek Harness Web UI,即可远程操作。
2、验证链路(命令与预期输出)
# 无凭据访问 → 401(认证生效)curl -I 服务器公网地址:对外端口# HTTP/1.1 401 Unauthorized ✅
# 带凭据访问 → 200curl -I -u admin:you_passwd 服务器公网地址:对外端口# HTTP/1.1 200 OK ✅3、WebSocket 实时通信
DeepSeek Harness 前端与后端通过 WebSocket 保持长连接,用于任务进度实时推送、Agent 执行日志流式输出、前端事件总线。这依赖 Nginx 正确转发升级握手:
proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";如果漏掉这两行,页面能打开但实时数据不更新,任务跑起来看不到进度,表现为「页面死了一样」。排障时优先检查这个。
4、页面主要功能如何远程操作
| 功能 | 说明 | 远程操作方式 |
|---|---|---|
| Agent 会话 | 与 Agent 对话、下发任务指令 | 新建/切换会话 → 输入指令 → Agent 执行过程实时回流到页面 |
| 评测任务 | 创建并运行评测,查看结果 | 配置评测参数 → 触发运行 → 通过 WebSocket 实时看进度 → 完成后查看结果 |
| session.history | 会话历史记录查询 | 页面内直接浏览历史会话,跨设备共享,工作记录不丢 |
| 文件/产物 | Agent 任务产物、上传文件 | 页面内上传/下载(依赖 client_max_body_size 20m 放宽请求体) |
远程操作的核心体验差异就是「实时性」:WebSocket 断流 → 进度卡住;Host 头不对 → 接口 403;浏览器兼容性 → 前端 JS 报错。把这三点提前想明白,远程使用基本就顺畅了。
六、管理 deepseek-harness
1、管理脚本:dsh-manage.sh
四合一管理脚本,基于 systemd,提供 start / stop / restart / status 四个操作。放在项目目录下即可:
#!/bin/bash# 用法:# bash dsh-manage.sh start 开启 DeepSeek Harness# bash dsh-manage.sh stop 关闭 DeepSeek Harness# bash dsh-manage.sh restart 重启 DeepSeek Harness# bash dsh-manage.sh status 查看运行状态
SERVICE="dsh-web" # DeepSeek Harness 的 systemd 服务名WAIT_SECONDS=5 # 操作后等待秒数URL="服务器公网地址:对外端口"
case "$1" in start) echo ">>> 正在开启 DeepSeek Harness ..." systemctl daemon-reload systemctl start "$SERVICE" sleep "$WAIT_SECONDS" if systemctl is-active --quiet "$SERVICE"; then echo "[OK] 已开启,访问地址: $URL" else echo "[ERROR] 开启失败,最近日志:" journalctl -u "$SERVICE" -n 20 --no-pager exit 1 fi ;; stop) echo ">>> 正在关闭 DeepSeek Harness ..." systemctl stop "$SERVICE" sleep 2 if systemctl is-active --quiet "$SERVICE"; then echo "[ERROR] 正常停止失败,强制终止..." systemctl kill "$SERVICE" sleep 2 fi if systemctl is-active --quiet "$SERVICE"; then echo "[ERROR] 关闭失败,请手动检查: journalctl -u $SERVICE" exit 1 else echo "[OK] 已关闭" fi ;; restart) echo ">>> 正在重启 DeepSeek Harness ..." systemctl daemon-reload systemctl restart "$SERVICE" sleep "$WAIT_SECONDS" if systemctl is-active --quiet "$SERVICE"; then echo "[OK] 已重启,访问地址: $URL" else echo "[ERROR] 重启失败,最近日志:" journalctl -u "$SERVICE" -n 20 --no-pager exit 1 fi ;; status) systemctl status "$SERVICE" --no-pager ;; *) echo "用法: bash $0 {start|stop|restart|status}" exit 1 ;;esacexit 0使用与验证:
bash -n 部署目录/dsh-manage.sh # 语法检查通过(无输出)chmod +x 部署目录/dsh-manage.shbash 部署目录/dsh-manage.sh start # 开启bash 部署目录/dsh-manage.sh restart # 重启验证bash 部署目录/dsh-manage.sh status # 状态赋予执行权限后即可用 bash dsh-manage.sh {start|stop|restart|status} 调用;也可在**系统定时任务(cron)**中配置 Shell 脚本定时调用,实现巡检 / 守护。
例如在任务调度系统中配置如下定时任务:
DeepSeek Harness 与 Nginx 的定时任务调度列表
2、日志位置速查
| 日志 | 位置 | 说明 |
|---|---|---|
| DeepSeek Harness 应用日志 | /var/log/dsh-web.log | systemd 服务的 stdout/stderr(追加写入) |
| Nginx 访问日志 | /var/log/nginx/dsh-access.log | 对外端口全部请求 |
| Nginx 错误日志 | /var/log/nginx/dsh-error.log | Nginx 层错误(含代理 / 认证问题) |
| systemd 日志 | journalctl -u dsh-web | systemd 托管日志(管理脚本报错时使用) |
tail -f /var/log/nginx/dsh-access.log # 实时看访问tail -f /var/log/dsh-web.log # 实时看应用日志journalctl -u dsh-web -n 50 --no-pager # 看 systemd 日志3、常见操作速查
| 操作 | 命令 |
|---|---|
| 修改 DeepSeek Harness 服务配置 | 编辑 dsh-web.service → systemctl daemon-reload → systemctl restart dsh-web |
| 修改 Nginx 配置 | 编辑 dsh.conf → nginx -t → nginx -s reload |
| 修改 Basic Auth 密码 | htpasswd -B 部署目录/dsh-auth/dsh-htpasswd admin → nginx -s reload(保持权限 -rw-r----- root nginx) |
| 查看端口占用 | ss -lntp |
| 查看内存 | free -h |
记住两件事:改 systemd 必须
daemon-reload;改 Nginx 必须先nginx -t再 reload。
七、总结
这次云部署 DeepSeek Harness 的最终方案可以概括为三句话:
- 对外:Nginx + 对外端口 + Basic Auth 访问认证;
- 对内:DeepSeek Harness 的 web 服务只监听回环地址,由 Nginx 反代,systemd 托管守护;
- 排障:三次典型问题(Host 信任、randomUUID 兼容性、回环 fence)本质是一条信任链的逐层打通。
整套方案的关键文件如下,方便日后速查:
| 类型 | 位置 / 值 |
|---|---|
| 仓库目录 | 部署目录/deepseek-harness(固定提交 47f943859b) |
| Nginx 配置 | Nginx 站点配置目录下的 dsh.conf |
| Basic Auth 密码文件 | 部署目录/dsh-auth/dsh-htpasswd(账号 admin) |
| systemd 服务 | /etc/systemd/system/dsh-web.service(服务名 dsh-web) |
| 管理脚本 | 部署目录/dsh-manage.sh |
| 应用日志 | /var/log/dsh-web.log |
| Nginx 日志 | /var/log/nginx/dsh-access.log、/var/log/nginx/dsh-error.log |
| 后端监听 | 127.0.0.1:后端端口 |
| 对外访问 | 服务器公网地址:对外端口(Basic Auth:admin / 自设强密码) |
八、最终效果
部署完成后,浏览器打开 服务器公网地址:对外端口,输入 Basic Auth 凭据登录,即可进入 DeepSeek Harness Web UI 远程操控 Agent:




