• 请不要在回答技术问题时复制粘贴 AI 生成的内容
longbill
V2EX  ›  程序员

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

  •  
  •   longbill · 3h 24m ago · 145 views

    适用场景:你有一台服务器,想把 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 web:实际服务,监听 127.0.0.1:3080
    • dsh-webui-auth 插件: 登录认证(未认证的浏览器拿不到任何资源)
    • pm2: 守护进程 + 开机自启
    • nginx: 对外入口,反代 + 移动端缩放 + manifest 直出

    第一步:安装 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 不会丢。

    访问与验证

    • 电脑:浏览器打开 http://你的域名,登录后正常使用;
    • 手机:同样地址登录。验证 PWA:Chrome 菜单 →「添加到主屏幕」; DevTools → Application → Manifest ,display 应为 standalone
    • 如果手机或电脑上看到的是旧页面,记得硬刷新清缓存。

    常见问题

    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 (系统对话框弹在服务器屏幕上,远程用户看不到也点不了)

    No Comments Yet
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   967 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 19:01 · PVG 03:01 · LAX 12:01 · JFK 15:01
    ♥ Do have faith in what you're doing.