Skip to content

CH 27 · 部署形态选型

全文字数4206 字预估耗时约 25 分钟前置CH 03、CH 05难度可照做

本章目标

前面你一直在本地用 dsh web 跑 dsh——这是最常见的一种形态,但不是唯一的。dsh 主要有四种跑法,各自适合不同场景:

  • 本地 Web UI:就是前面教程一直演示的那种
  • Headless CLI:不需要界面,一条命令跑完一个任务就退出,适合塞进脚本和 CI
  • Python SDK:把 dsh 嵌进你自己写的 Python 程序里,Agent 变成你代码里的一个函数调用
  • Docker 容器化:把 dsh 装进容器跑在服务器上,适合团队共用——这一章会给完整部署教程

读完你就知道:自己的需求该用哪种跑法,而不是只会 dsh web

先搞清楚:dsh 为什么有多种形态

回到 CH 08 讲的"一切皆插件"——dsh 的核心是 @deepseek-ai/dsh-base(模型适配器、工具、持久化、沙箱、审批这些底层能力),在它上面叠不同的 bundle,就变成不同的形态:

叠上去的 bundle变成什么启动方式
@deepseek-ai/dsh-web-app带浏览器界面的 Web UIdsh web
@deepseek-ai/dsh-headless无界面、跑完就退的命令行dsh --profile headless "任务"
Python SDK 封装嵌进 Python 程序里调用pip install deepseek-harness-sdk
以上任意一种装进容器服务器上长期运行docker compose up -d

同一个底层,四种穿法。这也是"一切皆插件"的又一次体现——形态本身就是 bundle 的组合。

形态一:本地 Web UI

前面 CH 03 到 CH 04 一直在演示的就是这种。dsh web 启动,浏览器打开 http://127.0.0.1:3080,会话、插件、密钥都存在本地。

适合个人日常使用、调试插件、初学者。局限是必须电脑开着才能用——电脑一关 Agent 就停了,不适合需要 7x24 在线、或让别人随时访问的场景。

形态二:Headless CLI

CH 05 已经实操过了。没有界面,给一个任务跑完输出结果就退出。

powershell
dsh --profile headless "把当前目录的 README 总结成三句话"

适合塞进脚本、CI/CD、定时任务(CH 15 那个每天抓 AI 热点的任务用的就是它)、批量处理。不适合需要多轮对话的场景。

一个边界:headless 每次调用是一个独立的会话,跑完就结束。要复用上下文得用 Python SDK,或写文件中转。

形态三:Python SDK

把 dsh 变成 Python 代码里的一个库,Agent 就是一个函数调用。pip install deepseek-harness-sdk 装上,SDK 自带 Node 运行时,目标机器不需要单独装 Node。

python
from deepseek_harness_sdk import DeepSeekHarness

dsh = DeepSeekHarness()
result = dsh.run("把当前目录的文件名列出来,跳过 node_modules")
print(result.last_message)

适合把 Agent 嵌进自己的产品、需要精细控制会话(复用、事件监听、流式输出)、批量任务共享上下文。不适合只想快速跑一个任务(headless 一条命令就够了)。

一个细节:SDK 和 Web UI 是两个独立实例,不能共用运行中的 Web UI,各有各的 DSH_HOME

形态四:Docker 容器化(完整部署教程)

把 dsh 装进 Docker 容器,跑在服务器上,适合长期运行、团队共用。

上服务器之前先说两句:没有服务器的话,腾讯云新用户活动经常有低价轻量应用服务器,100出头一年,跑 dsh 绰绰有余。另外腾讯云现在创建实例的时候已经可以直接选 DeepSeek Harness 镜像直装了,喜欢折腾的可以自己研究一下。下面用社区一个成熟的开源项目演示完整部署流程。

deepseek-harness-web-docker把 dsh + Caddy(反向代理 + Basic Auth 认证)打包成一个容器,开箱即用,数据持久化,还有自动健康检查。

这个项目解决了什么问题

直接用官方 dsh web 上服务器有三个痛点:

  1. 没有认证——dsh Web UI 默认没有登录机制,公网部署等于裸奔
  2. 只监听回环——默认 127.0.0.1,要改配置才能让外部访问
  3. 环境管理麻烦——Node 版本、依赖、数据目录都得自己管

这个项目用 Caddy 做反向代理,加了 Basic Auth(用户名密码登录),dsh 只在容器内部监听回环,外部请求必须经过 Caddy 认证才能进来。数据全部挂载到宿主机的 ./data 目录,删容器不丢数据。

第 1 步:准备

一台 Linux 服务器(2 核 2G 起步),装好宝塔面板。宝塔 AI 需要先配置好模型才能用——进宝塔左侧菜单的 AI → 顶部 设置 → 点 添加自定义模型,把你的模型 API Key 填进去就行。

宝塔面板添加自定义模型

配好模型后,宝塔 AI 就能帮你执行命令了。

第 2 步:宝塔 AI 一键部署

宝塔面板左侧菜单点 AI,把下面这段提示词发给它:

text
帮我部署 DeepSeek Harness Web Docker,按顺序做:
1. 确认 Docker 和 Docker Compose 已装好,没有就装
2. 项目地址是 https://github.com/Xidong-AI/deepseek-harness-web-docker
3. 进入项目目录,cp .env.example .env
4. 编辑 .env:DSH_AUTH_USER=admin,DSH_AUTH_PASSWORD设一个强密码,DEEPSEEK_API_KEY等等启动之前你告诉我文件路径我自己去填
5. docker compose up -d 启动
6. 验证成功后给我一个总结

宝塔 AI 会帮你完成。跑到第 4 步时,它会把 .env 文件里除 API Key 之外的项都配好,然后告诉你文件路径,让你自己把 DEEPSEEK_API_KEY 填进去:

宝塔 AI 提示填写 .env 的 API Key

填好后回复「填好了」,AI 会继续执行 docker compose up -d 启动,然后做健康检查验证,最后给你一份完整总结:

宝塔 AI 验证部署成功

看到容器状态是 healthy、Basic Auth 生效(不带凭据返回 401),就说明部署成功了。

第 3 步:访问

浏览器打开 http://服务器IP:3080,会弹出 Basic Auth 登录框,输入你在 .env 里设的用户名和密码,就能进入 dsh Web UI 了。

注意浏览器左上角会显示「不安全」——这是因为当前用的是 HTTP 协议,没有 SSL 证书,不是 dsh 本身的问题。正式部署建议绑域名 + HTTPS(下一步讲)。

浏览器访问显示不安全

进去之后和本地用的 dsh 一模一样——选工作目录、发消息。

第 4 步:绑定域名 + HTTPS

正式环境必须绑定域名 + HTTPS 才能正常使用。用 http://服务器IP 直接访问的话,选择工作区时会报这个错:

选择工作区时报 crypto.randomUUID 错误

原因是 crypto.randomUUID() 是浏览器 Web API,标准规定它只在安全上下文可用——也就是 https:// 页面,或 localhost/127.0.0.1。用 http://IP 访问属于不安全上下文,这个函数是 undefined,前端一创建会话、选择工作区就抛 crypto.randomUUID is not a function

所以绑域名 + HTTPS 不是可选优化,是必须做的。

前提:先去你的域名管理控制台(腾讯云 DNSPod、阿里云万网等),给域名加一条 A 记录,指向你的服务器公网 IP。等几分钟让解析生效。

接着刚刚那个对话继续(不用新开),把下面这段发给宝塔 AI:

text
帮我给刚部署好的 dsh 绑定域名和申请SSL证书配置好给我
1. 域名是 你的域名,已经解析到这台服务器了
2. 验证 https://你的域名 能正常访问,告诉我结果

宝塔 AI 会自动修改 Caddy 配置、放行端口、重启容器、申请证书。完成后访问 https://你的域名,浏览器左上角就会显示小锁图标,不再是「不安全」了。

证书是 Let's Encrypt 签发的,Caddy 会自动续期,不用手动管。

后续维护

部署完之后,日常有什么问题直接问宝塔 AI 就行,比如:

  • "怎么升级 dsh 容器到最新版本?"
  • "怎么查看 dsh 容器的运行日志?"
  • "怎么重启 dsh 容器?"
  • "怎么备份 dsh 的数据?"
  • "dsh 容器占磁盘空间太大了,怎么清理?"

它会根据你的实际环境给出对应的命令并执行。数据都存在项目目录的 ./data/ 下,删容器、升级镜像都不会丢数据,要备份把整个 ./data 目录拷走就行。

容器里能装什么工具

容器里预装了 node 22、pnpm、python3、git、curl、jq、ripgrep、make/gcc(编译原生模块用)、Rust 等常用工具。Agent 还能通过 x-cmd 自行安装更多工具(不需要 root),装完的数据也存在 ./data 里,重启不丢。

注意事项

  1. 当前版本 dsh 没有多用户隔离——所有人用同一个 Basic Auth 登录后,看到的是同一份会话和配置。团队共用时不要存敏感信息,或者每人部署一个独立实例。
  2. API Key 别写死在 compose 里——用 .env 文件,项目已经把它 git-ignore 了。
  3. Agent 在容器里干活——它看到的文件系统是容器内部的,不是你服务器的。要让它操作你服务器上的某个目录,得在 docker-compose 里加 volume 挂载,把宿主机目录映射进容器。
  4. 改密码:编辑 .env 里的 DSH_AUTH_PASSWORD,然后 docker compose up -d,容器启动时会自动重新生成哈希。

怎么选:一张表说清

你的需求选哪种为什么
每天打开浏览器跟 Agent 干活本地 Web UI界面直观,能看轨迹和审批
塞进脚本 / CI / 定时任务Headless CLI一条命令,跑完就退
把 Agent 嵌进自己写的程序Python SDK函数级调用,能控会话和事件
服务器长期跑 / 团队共用Docker容器化部署,自动重启,数据挂载
批量任务需要共享上下文Python SDKheadless 每次是独立会话,SDK 能复用

一个实用建议:大多数人从本地 Web UI 开始就够了。用到自动化了再加 headless,要嵌产品了再上 SDK,要上服务器了再 Docker。不用一开始就把四种都配齐——dsh 的好处就是按需切换,底层是同一套东西。

这一章你学到了什么

能自己完成下面几条,就算过关:

  • [ ] 知道 dsh 有四种部署形态:本地 Web UI、Headless CLI、Python SDK、Docker
  • [ ] 知道四种形态各自的启动方式和适用场景
  • [ ] 能根据需求选对形态——而不是只会 dsh web
  • [ ] 知道 Headless 每次调用是独立会话,要复用上下文得用 SDK
  • [ ] 知道 Python SDK 自带 Node 运行时,且和 Web UI 是独立实例
  • [ ] 能用 deepseek-harness-web-docker 项目在服务器上部署带 Basic Auth 的 dsh
  • [ ] 能给部署好的 dsh 绑定域名 + HTTPS(Caddy 自动证书)
  • [ ] 知道 Docker 部署的注意事项:无多用户隔离、密钥用 .env、容器内路径差异

Open Source · MIT · Community Driven