dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
Community Docker and Kubernetes packaging for DeepSeek Harness (@deepseek-ai/dsh), with a hardened image, Compose stack, Helm chart, Web UI, and headless CLI.
English | 简体中文
DeepSeek Harness 最早一批非官方 Docker 镜像项目之一,自 2026 年 8 月 13 日 起持续维护。 提供 Docker Hub / GHCR 双架构镜像、Docker Compose、Rootless Podman 和 Helm 部署,持续跟进官方版本。
默认运行官方 @deepseek-ai/dsh 的 Web UI,将官方 npm 发行物装入非 root 的 Node.js 24 运行时,集成可视 Chromium/noVNC 桌面,并提供可选的插件市场和受保护局域网入口。镜像不修改 DeepSeek Harness 源码。
当前基线:@deepseek-ai/dsh@0.2.1-rc.2。DeepSeek Harness 仍处于预发布阶段;升级前应重新完成本文的构建和 Smoke Test。0.2.1-rc.2 直接对应官方 dsh-v0.2.1-rc.2 Release 与 npm Registry 的 @deepseek-ai/dsh@0.2.1-rc.2,并非本项目自定义版本。本项目封装 npm 成品而不从源码构建,因此以可安装的官方发行物为基线,并故意不发布漂移的 Docker latest 标签。
0.2.1-rc.2 新增 DeepSeek-V4.1-Flash-1017 支持,并接入可在网页搜索设置中开启的 DeepSeek Search / Fetch API。npm dist-tag 可能滞后,本项目始终固定完整版本;升级不会自动启用这些 API。
alpha.4 插件兼容性: 第三方插件声明的 engines.dsh 优先用于判断 DSH 版本兼容性;未声明时继续沿用原有规则。升级第三方插件时应核对其支持范围。alpha.3 迁移提醒: Web / Desktop 优先使用已保存凭据;Headless 默认只读取环境变量和.env,不再读取已保存密钥。旧 Azure provider 名称azure-openai-responses需迁移为azure。--from-default-profile重建已有自定义 Profile 会替换其插件和设置,升级现有实例时请保留原 Profile。详见官方更新说明。
升级提醒:0.1.7-alpha.1起 Session 日志为 V4。若从更早版本升级,必须先备份dsh-home;依赖旧日志结构的工具需要适配 V4,降级前也应恢复升级前的卷备份,而不是让旧版直接读取已迁移数据。
兼容性提醒: 自定义spill-policy配置必须把maxInlineBytes改为按估算 Token 计数的maxInlineTokens。内置 E2B 执行后端已移除,PTC 与 Workflow 服务已重命名;若从0.1.7-alpha.1以前升级,还需处理 Messages-only adapter、Profile-owned 设置、Bundle Agent Preset 和 RemotereadBytes迁移。详见官方 Release。
0.2.1 兼容性提醒: 自动化任务重新成为 Web 内置能力,旧实验组合包选择会自动清理但已有任务保留。运行时 invariant 插件及各包的./invariant导出已移除;子路径插件不再读取独立package.json;输入区原stats扩展拆为activity与usage。依赖这些入口的自定义插件必须先适配。
alpha.2 迁移提醒: 工具展示模式移除both,仅保留native与ptc;自定义 Python PTC 组合需提供sandbox和sandboxPolicy。agent-instructions不再接受逐行dshHome,应使用进程级DSH_HOME;自定义子代理 SDK runtime 需支持session/wait,Agent Team 的 outbox、重试和去重配置也需迁移。本镜像继续保留回环端口与现有 Caddy LAN 入口,不会因上游新增原生 HTTPS 而自动开放网络访问。详见官方更新说明。
上游版本跟踪:每日运行的 Upstream DSH version watch 会同时检查 GitHub Release 与 npm。若新版 Release 已发布但 npm 制品尚不可用,工作流会创建或刷新等待 Issue 并保留当前可安装基线;同版本 npm 包可安装后,Issue 会自动切换为升级提醒,固定版本追平后再自动关闭。
📖 延伸阅读:DeepSeek Harness GitHub 仓库深度解析 · Docker、Compose 与 Helm 部署实战
🤖 Agent Skill:根目录的 SKILL.md 已作为 deepseek-harness-docker 发布到腾讯云 SkillHub,可供支持 Agent Skills 的客户端安装和使用。它指导 Agent 按本项目的安全边界完成 Docker Compose/Helm 部署、验证、升级与排障;这是部署辅助 Skill,不是 DSH 运行时插件。
_浅色界面实拍(2026-10-17,DSH 0.2.1-rc.2)。使用独立空白演示工作区,不包含个人会话或凭据,未配置模型,也未发起模型调用。_
能力 · 状态 · 验证结果 Dockerfile · 可用 · linux/arm64、linux/amd64 构建与原生 PTY 实际启动均已验证 Docker Compose · 可用 · Web token/cookie 认证、healthy、回环端口、重启持久化已验证 Rootless Podman · 可用 · keep-id 用户映射、bind mount 写入、命名卷持久化与回环端口已纳入 CI Helm · 可用 · 单副本 StatefulSet、PVC、Headless Service、NetworkPolicy;helm lint --strict 通过 Web UI · 本机默认;可选受保护 LAN · 默认仅回环访问;LAN overlay 提供 HTTPS、Basic Auth、DSH token/cookie 与同源 noVNC Headless · 可用 · 运行时注入 provider Secret;需在目标环境验证实际模型调用和沙箱 Chromium · 默认 + 可选隐私变体 · Debian Chromium 默认镜像;独立 ungoogled-chromium 双架构镜像会验证无 GCM :5228 活动
本节是配套技术文章的精简版。Cordis 架构、Agent 轮次和事件溯源持久化见 GitHub 仓库深度解析;镜像设计、安全模型和容器验证矩阵见 Docker、Compose 与 Helm 部署实战。
DeepSeek Harness 不是 DeepSeek 模型权重或推理引擎,而是一套 TypeScript AI Agent Runtime。它把模型适配、会话、工具、权限、工作区、插件、Web UI 与 Headless 入口装配在一起,最终发布为 @deepseek-ai/dsh CLI。更合适的专题归类是“AI Agent Runtime 的云原生化”,而不是“LLM 推理部署”。
截至 2026-08-13,上游仓库还没有 Dockerfile、Compose 或 Kubernetes 清单;同时 CONTRIBUTING.md 明确表示暂不接受外部 Pull Request,并鼓励社区创建生态项目和教程。因此本项目采用独立社区实现,而不冒充官方镜像。
flowchart TB
CLI["dsh CLI"] --> PROFILE["Profile + Bundle + --patch layers"]
PROFILE --> CORDIS["Cordis plugin graph"]
CORDIS --> CORE["Agent / Session / Model / Tool / Sandbox"]
CORDIS --> WEB["Web surface :3080"]
CORDIS --> HEADLESS["Headless surface"]
CORE --> WORKSPACE["/workspace"]
CORE --> HOME["DSH_HOME: profiles / settings / credentials / sessions / storage"]dsh web 是 Web profile 的快捷入口,dsh --profile headless 则走一次性或自动化场景。Profile 不是一份封闭配置,而是基础 bundle、界面 bundle、用户 patch 和命令行 --patch 按顺序叠加的结果。id 覆盖目标行。本项目没有 fork 源码,而是复用这条官方扩展缝隙覆盖容器监听地址。$DSH_HOME 数据模型。DSH_HOME 是容器化的关键边界。本项目显式设为 /home/node/.dsh,其中会出现:
profiles/:profile 的包清单、Cordis 配置和用户 patch;settings.yaml 与凭据文件:模型设置及 Secret 引用/托管凭据;sessions/:会话日志;storages/:Workspace 等领域状态。工作代码位于 /workspace,与内部状态卷分离。Compose 使用 dsh-home 命名卷加工作区 bind mount;Helm 使用 dsh-home PVC,并允许通过 workspace.existingClaim 挂载另一块工作区 PVC。这个分离让镜像可以重建,而会话与配置不会随容器消失。
npx难点 · 上游行为 · 本项目决策 Node / glibc · 要求 Node 22.19+ 或 24+;部分用户二进制需要较新 glibc · 固定官方 node:24-trixie 非 slim,Debian 13 / glibc 2.41 原生依赖与 Agent 工具 · node-pty 或第三方插件可能需要本机构建;Agent 需要常见开发命令 · 多阶段安装 DSH;runtime 有意保留 buildpack-deps 工具链,并补齐 jq、less、ripgrep、rsync、zip 等命令 Web 监听 · 0.2.1-alpha.2 起配置层也拒绝通配地址 · DSH 监听回环;单个具体容器 IP 做 TCP 转发;宿主 3080/6080 只发布到 127.0.0.1 Web 安全 · 有启动 token 认证与 Host/Origin 检查,可选原生 TLS;noVNC 无认证,工具可触发代码执行 · 容器默认 HTTP、回环发布;可选 Caddy HTTPS + Basic Auth;不提供公网 Ingress/LoadBalancer HMR · 启动后挂载配置 watcher,需要 Node internals · 仅给 DSH 主进程传 --expose-internals,不通过 NODE_OPTIONS 传播给 Agent 子进程 目录选择器 · 浏览模式以 os.homedir() 为首页 · 将 HOME 指向可写 /workspace,避免只读 /home/node 的 EROFS 信号和子进程 · Agent 会创建 shell/PTY 子进程 · 使用 tini 转发信号和回收孤儿进程 权限 · 工具需要工作区写入,但不应获得宿主权限 · UID 1000、只读根文件系统、drop ALL、no-new-privileges、最小挂载
默认基础镜像选择非 slim 是面向 coding agent 的明确取舍,而不是追求最小体积。Debian 13 Trixie 将 glibc 从 Bookworm 的 2.36 提升到 2.41,能运行更多按新系统构建的二进制;官方 Node 非 slim 变体基于 buildpack-deps,自带编译器、make、git、curl、file、unzip、wget、xz 等开发工具,本项目再显式安装 jq、less、ripgrep、rsync 和 zip。代价是基础镜像压缩体积比 slim 大约增加 330 MB;Smoke Test 会同时检查 Trixie、glibc 2.41 和完整命令清单,避免后续升级意外退化。
这里最需要强调的是 Web 监听:0.2.1-alpha.2 开始,Harness 的 CLI 和配置层都拒绝通配地址。本项目让 DSH 保持监听 127.0.0.1:3080,由入口脚本在单个具体容器 IP 上启动 TCP 中继,原样转发到回环地址,不修改 DSH 源码,也不改写 token、Cookie、Host/Origin 或 WebSocket 流量。这样既支持 Docker/Podman 端口映射,也保留 Kubernetes port-forward 和容器内健康检查。默认自动选择唯一的非回环 IPv4 地址(仅 IPv6 时选唯一的非链路本地地址);多网卡存在歧义时拒绝启动,需显式设置 DSH_WEB_RELAY_INTERFACE。不支持 host networking 或 --port 0。
默认 Compose 仍只发布宿主 127.0.0.1。需要受信任局域网访问时,显式叠加 compose.lan.yaml,由 Caddy 在指定 LAN 地址上终止 HTTPS、增加 Basic Auth,并把 noVNC 收进同一认证入口;DSH 仍执行自己的启动 token、签名 Cookie 与 Host/Origin 检查。直接改成 -p 3080:3080、NodePort、LoadBalancer 或公开 Ingress 仍会破坏这个安全模型。
容器不是 Harness 内部权限系统的替代品,两层保护的对象不同:
Linux Landlock、用户命名空间和原生 helper 的可用性会受宿主内核与容器运行时影响。本项目不会用 --privileged、Docker socket 或额外 capabilities 掩盖沙箱失败。发布前除“页面能打开”外,还必须在目标平台验证一次真实 bash/文件工具调用。
若内核已经编译 Landlock、但没有放进当前 LSM 列表,应优先按发行版方式启用 Landlock 并重启;不要照搬其他发行版的 GRUB 命令,先核对 /proc/cmdline、内核配置和引导工具。若内核根本没有 Landlock(常见于部分 NAS/Appliance 内核),可在 Docker Compose 上显式使用 bubblewrap 变体:
DSH_WORKSPACE=/absolute/path/to/project \
docker compose -f compose.yaml -f compose.bwrap.yaml pull
DSH_WORKSPACE=/absolute/path/to/project \
docker compose -f compose.yaml -f compose.bwrap.yaml up -d --no-build该 overlay 使用不可变镜像 runzhliu/deepseek-harness:0.2.1-rc.2-r1-bwrap.1,并增加 seccomp=unconfined 与 systempaths=unconfined,使非 root 的 bwrap 可以创建内部 user/mount/PID namespace 和挂载新的 /proc。它仍保留 UID 1000、只读根文件系统、cap_drop: ALL、no-new-privileges 和最小挂载;但两项设置确实扩大了外层容器可见的系统调用与 /proc 表面,因此不会成为默认配置。宿主还必须允许非特权用户命名空间。
此方案当前只承诺 Docker Compose,不应用于 rootless Podman 或 Kubernetes。Podman 主机若内核已有 Landlock,应优先在启动参数中启用对应 LSM。可以在目标 Docker 主机复现隔离边界测试:
make bwrap-build
make bwrap-smoke测试会证明 bubblewrap 内 /workspace 可写,同时即使外层额外挂载一个可写目录,模型命令也无法写入该目录。相关背景和宿主案例见 Issue #35。
Harness 的 profile、模型设置、凭据、会话和 Workspace 索引都具有状态。单用户 Web 又不适合在没有会话协调的情况下横向扩容。因此 Helm Chart 固定一个 StatefulSet 副本:稳定地挂载 dsh-home PVC,升级时保留状态,卸载时保留 PVC,并明确拒绝把“加 replicas”伪装成高可用。未来只有在上游提供外部身份、多租户隔离和共享/并发安全的状态后端后,才适合讨论多副本服务化。
FROM node + npx这个镜像处理了最容易漏掉的四个容器边界:
dsh plugin add 能在运行时管理社区插件;tini,正确处理 Agent 启动的子进程与退出信号;/home/node/.dsh;/workspace,让 Web 目录选择器的新建操作落在可写工作区;127.0.0.1。DeepSeek Harness Web 会用启动 token 换取签名浏览器 Cookie,并检查 Host/Origin;但本镜像默认使用 HTTP,Web API 可以执行代码,noVNC 端口也没有认证。因此默认方案是本机单用户开发环境。局域网访问必须使用下方显式启用的受保护入口;公网暴露不在支持范围内。
在本目录执行:
docker compose pull
DSH_WORKSPACE=/absolute/path/to/your/project docker compose up -d --no-build
docker compose ps
docker compose logs --no-color deepseek-harness | grep 'dsh web:'打开日志中 dsh web: 后面带 ?token=... 的完整 地址。Harness 会把当前进程的启动 token 换成签名 Cookie,再跳转到干净的根路径;直接打开不带 token 的根地址会返回 401。进入后在设置页配置模型和凭据。侧边栏的“浏览器桌面”按钮会在 Harness WebUI 内直接打开可交互的容器 Chromium;配置和浏览器 Profile 写入命名卷 dsh-home,重建容器后仍会保留。
未设置 DSH_WORKSPACE 时,Compose 使用独立的 dsh-workspace 命名卷,避免 Agent 意外修改本仓库。只有准备好明确的项目目录后,才通过 DSH_WORKSPACE=/absolute/path/to/project 改用 bind mount。
默认镜像修订版为 Docker Hub 上的 runzhliu/deepseek-harness:0.2.1-rc.2-r1,同一份多架构制品也会发布到 GitHub Container Registry:ghcr.io/runzhliu/deepseek-harness:0.2.1-rc.2-r1。r1 将同版本官方 Playwright MCP Browser Use attach 到可视 Chromium,并继续使用带版本的 noVNC 静态资源路径,避免升级后浏览器缓存混用不兼容的 ES Module。Compose 同时保留 build 配置,方便审查并从本目录复现镜像;如需本地构建,执行 docker compose build --pull 后再启动。
Podman 4.5 和 podman-compose 1.6.0 或更新版本可使用专用 compose.podman.yaml overlay。较旧的 podman-compose 1.0.x 不能正确替换多文件 Compose 中相同目标路径的挂载;若发行版仓库版本过旧,可先执行 pipx install 'podman-compose>=1.6.0'。该 overlay 把当前 rootless 用户映射为镜像内的 node UID/GID 1000,并为工作区添加私有 SELinux 标签;这样无需用 root 运行 DSH,也无需递归修改宿主项目所有权:
podman version
podman-compose version
podman info --format '{{.Host.Security.Rootless}}' # 应为 true
DSH_WORKSPACE=/absolute/path/to/your/project \
podman-compose -f compose.yaml -f compose.podman.yaml pull
DSH_WORKSPACE=/absolute/path/to/your/project \
podman-compose -f compose.yaml -f compose.podman.yaml up -d --no-build
podman-compose -f compose.yaml -f compose.podman.yaml ps这里明确使用 podman-compose,避免已安装 Docker Compose 时 podman compose 自动选中错误的外部 provider。Overlay 通过 x-podman.in_pod: false 关闭单服务部署不需要的 Pod 模式,因为 keep-id 用户命名空间不能与 --pod 同时使用。只挂载专用于该实例的项目目录;:Z 会在启用 SELinux 的主机上把该目录标记为本容器私有,不要对共享 home、仓库缓存或系统目录使用。停止服务使用 make podman-down,不会删除命名卷。维护者可运行 make podman-smoke 验证 rootless 身份、宿主文件所有权、重启持久化及回环端口。
若希望继续使用 Docker Compose 客户端,可启动 rootless Podman API socket,再让 Docker CLI 指向它;仍须叠加 compose.podman.yaml:
systemctl --user enable --now podman.socket
export DOCKER_HOST="unix://${XDG_RUNTIME_DIR}/podman/podman.sock"
DSH_WORKSPACE=/absolute/path/to/your/project \
docker compose -f compose.yaml -f compose.podman.yaml up -d --no-build需要从 GHCR 拉取时,设置镜像仓库即可,其他 Compose 配置保持不变:
DSH_IMAGE_REPOSITORY=ghcr.io/runzhliu/deepseek-harness docker compose pull
DSH_IMAGE_REPOSITORY=ghcr.io/runzhliu/deepseek-harness \
DSH_WORKSPACE=/absolute/path/to/your/project docker compose up -d --no-build不要直接发布 3080/6080。可选 compose.lan.yaml 在指定 LAN IP 提供 Caddy HTTPS + Basic Auth,保留 DSH token/cookie 与 Host/Origin 校验,并同源代理 noVNC。
先创建私有配置并生成密码哈希:
cp .env.lan.example .env.lan
docker run --rm -it caddy:2.11.4-alpine caddy hash-password编辑 .env.lan:填写确切 LAN IP(禁止 0.0.0.0)、客户端可解析的内网域名或 IP、单引号包裹的 bcrypt 哈希及可选工作区,然后启动:
make lan-up
make lan-logsCaddy 默认使用内部 CA。将根证书安装到受信任客户端的系统信任库:
docker compose --env-file .env.lan -f compose.yaml -f compose.lan.yaml \
cp lan-gateway:/data/caddy/pki/authorities/local/root.crt ./dsh-lan-root.crt从 dsh web: 日志 URL 取 ?token=...,首次用 https://DSH_LAN_HOST:8443/?token=... 打开。完成两层认证后即可使用干净地址。make lan-down 保留数据卷。8443 兼容 rootless 运行时。
该模式不是多租户:登录者共享会话、凭据及 Agent 权限;不互信用户须拆分实例和卷。用防火墙限制来源,禁止转发公网。make lan-smoke 可验证边界。
镜像内置 Debian Chromium、中文字体、Xvfb/Openbox 桌面和 noVNC,并把官方 @deepseek-ai/dsh-experimental-browser-use-playwright-mcp 以 mode: attach 连接到 http://127.0.0.1:9222。模型自动化和用户看到的是同一个 Chromium:共享标签页、Cookie、登录态与持久化到 /home/node/.dsh/chrome-profile 的 Profile。
层次 · 职责 DSH 官方侧边栏 Browser · 用 iframe 快速展示可嵌入的 HTTP(S) 页面,不向模型提供工具;0.1.7 起 Web 默认关闭。 DSH 官方 Browser Use · 用 Playwright MCP 负责页面检查、点击、输入、截图和提取。 @runzhliu/dsh-browser-desktop · 负责真实浏览器生命周期、持久化 Profile、可视桌面和人工接管。