把 DSH(DeepSeek Harness)部署到服务器:手机、电脑实时同步,云端开发

2 小时 27 分钟前
 longbill

适用场景:你有一台服务器,想把 DeepSeek Harness 的浏览器界面( Web GUI )跑在上面,让家里的电脑、公司的电脑、甚至手机浏览器都能登录使用,用 AI 帮你写代码、跑任务。本文基于 DSH 0.1.0-rc.6 + Ubuntu 22.04/24.04 + nginx + pm2 的实际部署经验整理。

为什么需要服务器 + 反代

DSH 的 Web 界面(dsh --profile web)默认只监听 127.0.0.1:3080,而且出于安全考虑**禁止 --host 0.0.0.0**( CLI 直接报错:防止把远程代码执行能力暴露到公网)。所以正确姿势是:

浏览器(手机/电脑)──► nginx ( 80/443 )──► dsh web ( 127.0.0.1:3080 )

nginx 做反向代理 + 登录保护 + 移动端适配,DSH 本身只在本机回环地址提供服务。


架构总览


第一步:安装 DSH

需要 Node.js ^22.19.0 || >=24.0.0

npm install -g @deepseek-ai/dsh
dsh --version   # 验证安装

第二步:初始化 web profile 并安装认证插件

dsh --profile web 首次运行时自动初始化 profile (目录在 ~/.dsh/profiles/web)。先装登录认证插件(需要 pnpm ,Node 自带 corepack ):

corepack enable pnpm
npx @deepseek-ai/dsh plugin --profile web add dsh-webui-auth

之后启动 web 服务,首次访问登录页时创建你的账号密码(存在 ~/.dsh/profiles/web/node_modules/dsh-webui-auth/dsh-webui-auth.json,密码是 scrypt 哈希):

dsh --profile web

补充:固定目录选择器为浏览器模式(服务器远程访问必做)

创建 ~/.dsh/patch.yml

# 固定目录选择器为「浏览器浏览」模式。
# 默认的 directory-picker-auto 会根据服务器环境自动选择:
#   - native:系统目录对话框,需要在服务器本机的显示器上操作;
#   - browse:浏览器内的目录列表(可浏览/新建子目录)。
# 服务器通过 nginx 反代远程访问时,native 对话框会弹在服务器自己的屏幕上,
# 远程的手机/电脑根本看不到,必须固定为 browse 。
# 注意:patch 无法直接改已有行的插件 name ,所以先禁用 auto 行,
# 再插入 browse 的主机端 + 客户端插件对。

- id: directory-picker
  disabled: true

- insert:
    - id: directory-picker-browse
      name: '@deepseek-ai/dsh-host-directory-picker-browse'
    - id: directory-picker-browse-ui
      name: '@deepseek-ai/dsh-client-ui-directory-picker-browse'

启动时用 --patch 挂上(见第四步的启动参数)。如果服务器上确实没有 DISPLAY/chooser 环境,auto 也会选 browse ,但显式固定可以保证任何环境下行为一致。

第三步:配置 API Key

~/.dsh/.credentials.yaml 写入:

DEEPSEEK_API_KEY: sk-你的密钥

(或通过环境变量 DEEPSEEK_API_KEY 注入,二选一即可。)

第四步:pm2 守护 + 开机自启

写 pm2 配置 ~/.dsh/pm2.json

{
  "apps": [
    {
      "name": "dsh-web",
      "script": "/usr/local/bin/dsh",
      "args": "--profile web --patch /root/.dsh/patch.yml --trusted-host 你的域名",
      "autorestart": true,
      "restart_delay": 3000
    }
  ]
}

--trusted-host 你的域名 必须加:Web 界面调用 /api 时有浏览器信任围栏,通过域名访问时 Host 不再是 127.0.0.1:3080,不加这个参数 API 会被拒。

启动并设置开机自启:

pm2 start ~/.dsh/pm2.json
pm2 save
pm2 startup 

第五步:nginx 反向代理

新建 /etc/nginx/sites-available/dsh.apple.me(域名换成你的),软链到 sites-enabled 并 reload:

ln -s /etc/nginx/sites-available/dsh.apple.me /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx

下面这份是完整最终配置,包含两个必踩的坑的解法(见注释),gzip/缓存为可选优化:

nginx 配置太长,点击这里访问我的博客,里面有 nginx 配置


坑 1:手机浏览器内容区域太小

现象:手机上打开 Web 界面, 工作区域宽度太窄,设置页面几乎没法用。

原因:页面 HTML 里的 viewport meta 是 initial-scale=1, 文字太大。

解法:在 nginx 上用 sub_filter 把响应里的 viewport 改成 0.7,让页面在手机屏上缩小显示。两个要点:

  1. 必须先 proxy_set_header Accept-Encoding ""; 把发给上游的压缩请求头置空,否则上游返回 gzip 压缩的 body ,sub_filter 的字符串替换会失效;
  2. sub_filter 默认只处理 text/html,HTML 页面正好符合。

改完 nginx -t && systemctl reload nginx,手机硬刷新(清缓存)后就能看到效果。


坑 2:manifest.webmanifest 请求永远是 302 ,PWA 装不上

现象:浏览器加载 <link rel="manifest"> 时请求 /manifest.webmanifest 一直被重定向到登录页( 302 ),DevTools 里 manifest 解析失败,手机"添加到主屏幕"不可用,display 模式也控制不了。

原因dsh-webui-auth 插件在 HTTP 层拦截了所有未认证请求(包括静态资源)并 302 到登录页。而浏览器拉取 manifest 的请求不会携带登录 Cookie ,于是永远 302 ,拿不到 manifest 内容。

解法:让 nginx 绕过认证,直接输出这份 manifest 文件——内容照抄 DSH dist 里的 manifest.webmanifest,并把 "display": "fullscreen" 改成 "standalone"( standalone 是"普通应用窗口",手机 PWA 更合适; fullscreen 会全屏隐藏浏览器 UI )。

要点:

  1. location = 精确匹配,只接管这一个路径,不影响其他资源;
  2. 内容硬编码在 nginx 里,以后 DSH 升级如果改了 manifest 结构需要手动同步;
  3. 不用改 DSH 源码,也不用给认证插件开白名单,改动全部在 nginx 层,升级 DSH 不会丢。

访问与验证

常见问题

  1. 想用 HTTPS?

用 certbot 申请证书,listen 443 ssl,并把 80 重定向到 443 (注意 443 的 location 也要带上同样的 sub_filter 和 manifest 直出配置)

  1. 改完 nginx 不生效?

nginx -t 先查语法,再 systemctl reload nginx,浏览器硬刷新

  1. 远程访问时"选择目录"没反应,或对话框弹在服务器本机屏幕上?

检查启动参数里是否带了 --patch /root/.dsh/patch.yml 固定 browse 目录选择器;不固定时 auto 可能选中 native (系统对话框弹在服务器屏幕上,远程用户看不到也点不了)

108 次点击
所在节点    程序员
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1234815

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX