CH 27 · 部署形态选型
本章目标
前面你一直在本地用 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 UI | dsh 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 已经实操过了。没有界面,给一个任务跑完输出结果就退出。
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。
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 上服务器有三个痛点:
- 没有认证——dsh Web UI 默认没有登录机制,公网部署等于裸奔
- 只监听回环——默认
127.0.0.1,要改配置才能让外部访问 - 环境管理麻烦——Node 版本、依赖、数据目录都得自己管
这个项目用 Caddy 做反向代理,加了 Basic Auth(用户名密码登录),dsh 只在容器内部监听回环,外部请求必须经过 Caddy 认证才能进来。数据全部挂载到宿主机的 ./data 目录,删容器不丢数据。
第 1 步:准备
一台 Linux 服务器(2 核 2G 起步),装好宝塔面板。宝塔 AI 需要先配置好模型才能用——进宝塔左侧菜单的 AI → 顶部 设置 → 点 添加自定义模型,把你的模型 API Key 填进去就行。

配好模型后,宝塔 AI 就能帮你执行命令了。
第 2 步:宝塔 AI 一键部署
宝塔面板左侧菜单点 AI,把下面这段提示词发给它:
帮我部署 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 会继续执行 docker compose up -d 启动,然后做健康检查验证,最后给你一份完整总结:

看到容器状态是 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() 是浏览器 Web API,标准规定它只在安全上下文可用——也就是 https:// 页面,或 localhost/127.0.0.1。用 http://IP 访问属于不安全上下文,这个函数是 undefined,前端一创建会话、选择工作区就抛 crypto.randomUUID is not a function。
所以绑域名 + HTTPS 不是可选优化,是必须做的。
前提:先去你的域名管理控制台(腾讯云 DNSPod、阿里云万网等),给域名加一条 A 记录,指向你的服务器公网 IP。等几分钟让解析生效。
接着刚刚那个对话继续(不用新开),把下面这段发给宝塔 AI:
帮我给刚部署好的 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 里,重启不丢。
注意事项
- 当前版本 dsh 没有多用户隔离——所有人用同一个 Basic Auth 登录后,看到的是同一份会话和配置。团队共用时不要存敏感信息,或者每人部署一个独立实例。
- API Key 别写死在 compose 里——用
.env文件,项目已经把它 git-ignore 了。 - Agent 在容器里干活——它看到的文件系统是容器内部的,不是你服务器的。要让它操作你服务器上的某个目录,得在 docker-compose 里加 volume 挂载,把宿主机目录映射进容器。
- 改密码:编辑
.env里的DSH_AUTH_PASSWORD,然后docker compose up -d,容器启动时会自动重新生成哈希。
怎么选:一张表说清
| 你的需求 | 选哪种 | 为什么 |
|---|---|---|
| 每天打开浏览器跟 Agent 干活 | 本地 Web UI | 界面直观,能看轨迹和审批 |
| 塞进脚本 / CI / 定时任务 | Headless CLI | 一条命令,跑完就退 |
| 把 Agent 嵌进自己写的程序 | Python SDK | 函数级调用,能控会话和事件 |
| 服务器长期跑 / 团队共用 | Docker | 容器化部署,自动重启,数据挂载 |
| 批量任务需要共享上下文 | Python SDK | headless 每次是独立会话,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、容器内路径差异
