云镜之端

DeepSeekHarness Docker版文档

  • 作者
  • 1 分钟阅读
评论
DeepSeekHarness Docker版文档

DeepSeek Harness (DSH) Docker 部署指南

概述

本仓库是 DeepSeek Harness 源码 + Docker 构建配置,用于将 dsh 打包为镜像并以 Web 模式(浏览器 UI)运行,默认端口 3080

构建流程(对应原始命令 git clonepnpm installpnpm run buildpnpm dsh web):

┌──────────┐   http://localhost:3080   ┌──────────────────────────┐
│ 浏览器    │ ────────────────────────▶ │  dsh web (Node 24)      │
└──────────┘                           │  监听容器内 0.0.0.0:3080  │
                                      └────────────┬─────────────┘
                              ┌───────────────────┼───────────────────┐
                              │ dsh-data 卷        │ ./workspace 挂载   │
                              │ /home/dsh/.dsh     │ /workspace        │
                              │ (会话/设置/配置)     │ (agent 工作目录)    │
                              └───────────────────┴───────────────────┘

镜像信息

已构建并推送的多架构镜像 registry.cn-hangzhou.aliyuncs.com/skymirror/dsh:latest(npm 安装路径镜像):

项目
DSH 版本0.1.2-alpha.2-skymirror.1(源码 commit 4d35ae4dee,同步自上游 dsh-v0.1.2-alpha.2
构建时间2026-09-01 03:22 UTC(北京时间 2026-09-01 11:22)
支持架构linux/amd64linux/arm64
manifest listsha256:4c8636d1f20804a39757829de5adb27dccf6435b99610e2a70e74fe8cc95b5bd
amd64 digestsha256:c7e0942b8dc38aa8787def4ba634ac967d767605d678ce010712df74e7195a2d
arm64 digestsha256:ea1226c71ddeb1675ed9355524dbe6ec5bd0f0431ce0a36bff9de63a7730779f
镜像大小单架构解压 ~0.91GiB(amd64 977,603,541 / arm64 977,698,548 字节实测;上一版全量镜像 2.7GB,缩减 64%),注册表压缩 amd64 302MiB / arm64 297MiB(上一版 ~0.9GB)
镜像来源dist/ npm pack 产物直接安装:生成器计算 CLI 依赖闭包(224 个 fork 包)以 file: 依赖离线安装,第三方依赖走 npmmirror;镜像内无 monorepo 源码(无 packages/ 工作区、无 pnpm-lock.yaml
内置环境Node.js 24.19 / Python 3.11 / pnpm 11.7.0 / Rust 按需安装 / gcc·g++ 12,详见下文「镜像内置语言运行环境」;JDK 与 Go 不再内置

历史构建存档(已被上表取代,哈希保留备查):

项目
历史 manifest listsha256:8a5d6406abd56f5cc3f175aa6b751e226bc91430dfb896add1fcf9a3f970f39e(2026-09-01 00:15 UTC,monorepo 源码编译镜像,单架构解压 ~2.7GB)
历史 amd64 digestsha256:c09248d31d641967fec21d78529ab41ee596c402545e0fd4cbeead17b63d41b5
历史 arm64 digestsha256:7295a2e5fcafa933c497b3eaa9fae279aeb85e0b6f44793602fd09f3046d0247

快速开始(使用已构建镜像)

docker pull registry.cn-hangzhou.aliyuncs.com/skymirror/dsh:latest
docker run -d --name dsh \
  -p 0.0.0.0:3080:3080 \
  -v dsh-data:/home/dsh/.dsh \
  -v "$PWD":/workspace \
  -e DSH_TRUSTED_HOSTS=your-server-ip \
  registry.cn-hangzhou.aliyuncs.com/skymirror/dsh:latest
# 浏览器认证:启动日志会打印 dsh web: http://<host>:3080/?token=<一次性令牌>。
# 执行 docker logs dsh 找到该行,把主机名换成 your-server-ip 后在浏览器打开;
# token 换取 30 天签名 cookie,之后在 Web UI 中配置模型 API Key 即可使用。

本次镜像包含的修复与变更

  • npm 安装路径:镜像不再编译 monorepo——构建时把 dist/ 的 npm pack 产物复制进镜像,docker/install-dsh-packages.mjs 从 tarball 元数据计算 CLI 依赖闭包(224 个 fork 包,testkit/examples/experimental 及其依赖的 ~616MB AI SDK 不进镜像),以 file: 依赖离线安装,registry 只服务第三方依赖;镜像内无 packages/ 工作区与 pnpm-lock.yaml
  • 体积与构建时间:镜像从全量编译的 ~2.7GB(解压)降到 ~0.91GiB(-64%),镜像构建只剩 apt 层 + npm install,显著快于 pnpm install + tsc/tsdown + vite 全量编译。
  • 双架构构建:buildx 一次产出 linux/amd64linux/arm64 两个平台的镜像。
  • 容器外访问:dsh web 默认绑定 0.0.0.0:3080(上游默认只监听 127.0.0.1),并保留 DSH_TRUSTED_HOSTS(显式信任,设置后替代上游自动信任局域网地址的行为)与 DSH_TRUST_ALL(请求级逃生口:同时跳过 Host/Origin 围栏与浏览器认证)两道开关。
  • 浏览器认证:随上游 0.1.2 采纳 BrowserAuth——启动 URL 携带一次性 token,仅在 GET / 有效,换取 30 天签名 cookie;此后每个 /api 方法与 WebSocket stream 都要求该 cookie。
  • 远程配置设置:settings / credentials 配置面对已认证的远程浏览器开放(浏览器认证统一覆盖所有方法,特权集机制上游已移除);客户端设置持久化固定 host,远程浏览器偏好持久化。访问控制由浏览器认证 + 上层 NGINX 承担;原生能力(目录选择器、打开设置文件、agent preset 创作、llm.discoverModels)不再有方法级回环钉死,但 UI 中的「打开设置文件」动作仍仅在本机浏览器展示。
  • 插件原生构建:内置 allowBuilds 预置,修复 pnpm 默认拦截原生依赖构建导致带 node-gyp 编译的插件(如 node-pty)安装失败的问题。
  • 构建稳健性:构建命令保留 DSH_CLIENT_COMMIT_HASH build-arg 与 --provenance=false --sbom=false(后者修复阿里云 ACR 拒绝 OCI attestation 清单导致推送失败的问题)。
  • 工具链调整:JDK/Go 不再内置(npm 路径镜像以精简为先),Python 3.11(apt 预编译)与 Rust 按需安装保留。

发布到 registry 后的重建路径(一行):fork 版本真实 publish 后,把 Dockerfile 中 COPY dist/ + 生成器安装换成 npm install -g @deepseek-ai/dsh@<dist-tag> --registry <私有 registry>(安装器语义不变),镜像即从 registry 拉取 fork 包,不再依赖本地 pack 产物。

前置条件

  • Docker Engine 20.10+(支持 BuildKit 多阶段构建)
  • Docker Compose v2(docker compose 命令)
  • 内存建议 ≥ 4GB(pnpm build 编译 Vite 前端较吃内存)

一、npm 安装(推荐,无需 Docker)

fork 版本已发布为 npm 包 @deepseek-ai/dsh(版本线 0.1.2-alpha.2-skymirror.*,发布在私有 registry),安装即用:前端产物随 @deepseek-ai/dsh-web-frontend 依赖分发,无任何构建步骤。

用户安装与启动

# 一次性配置私有 registry(放在用户级 ~/.npmrc 或项目 .npmrc 均可):
#   registry=<私有 registry 地址>   ← 由用户提供,如云效制品库 npm 仓库或 ACR npm 仓库
npx @deepseek-ai/dsh@alpha web           # 直接启动 Web UI(默认 0.0.0.0:3080,打印带 token 的访问 URL)
# 或全局安装后常驻使用:
npm install -g @deepseek-ai/dsh@alpha
dsh web --port 8080

浏览器打开启动日志打印的 dsh web: http://<host>:<port>/?token=<一次性令牌>(token 换取 30 天签名 cookie)。远程访问需要通过 /api 信任围栏,环境变量用法与 Docker 部署一致:DSH_TRUSTED_HOSTS=your-server-ip(显式信任,设置后替代自动派生局域网地址)或 DSH_TRUST_ALL=1(请求级逃生口:同时跳过围栏与浏览器认证,仅限可信网络)。需要 dsh plugin 管理插件时先 corepack enable pnpm(web 启动本身不需要 pnpm)。

要求 Node.js ^22.19 || >=24(CLI 包已声明 engines,旧版本 npm 会直接拒绝安装)。

版本与 dist-tag

fork 预发布版本(-skymirror.N 后缀)发布时自动落在 alpha dist-tag 上(上游发布序列规则:prerelease 首段为 alpha 的版本映射 alpha tag,不占用 latest)。因此:

npm view @deepseek-ai/dsh dist-tags --registry <私有 registry 地址>   # 查看 alpha/latest 指向
npx @deepseek-ai/dsh@alpha web                                       # 显式按 alpha tag 启动
# 若希望 @latest 命中 fork 版本:npm dist-tag add @deepseek-ai/dsh latest <版本> --registry <地址>

发布 fork 包(维护者)

发布完全复用上游发布序列(打包与发布分离、幂等、同完整性跳过),registry 由环境注入(NPM_CONFIG_REGISTRY 环境变量或 .npmrc),不硬编码任何 registry 地址:

pnpm run release:dsh 0.1.2-alpha.2-skymirror.1          # 1. 版本落盘:写全部 manifest + lockfile 并提交(本地执行)
pnpm run build:official                                  # 2. 官方构建(pack 校验构建记录)
pnpm run release:pack --family dsh --out dist/npm        # 3. 打包 245 个 tarball 到 dist/npm
pnpm run release:pack --family vendor --out dist/npm-vendor   # 4. vendor 家族(verify 需要)
pnpm --dir native/landlock-run run build:ts && \
  pnpm --dir native/landlock-run/packages/entry pack \
    --pack-destination "$PWD/dist/npm-landlock"          # 5. Landlock entry(verify 需要)
pnpm run release:verify-packed-install --family dsh \
  --from dist/npm --from dist/npm-vendor --from dist/npm-landlock   # 6. 安装冒烟:--version + dsh web HTTP 200
NPM_CONFIG_REGISTRY=<私有 registry 地址> \
  pnpm run release:publish --family dsh --from dist/npm  # 7. 发布(幂等;真实发布需要云效制品库 NPM_TOKEN 或 ACR npm 仓库凭据,由用户提供)

上游 release:pack --family dsh 打包 245 个包共约 8MB(CLI 包 15KB,前端 dist 随 @deepseek-ai/dsh-web-frontend 1.4MB)。

换 scope 发 npmjs(可选项,暂不采用):fork 也可以全树改名后公开发布到 npmjs(如 @skymirror/dsh),无需私有 registry。不采用的代价:236+ 个 manifest 与 import 位改名,且每次上游同步都要重做;@deepseek-ai scope 的发布权在上游维护者,fork 包无法以原名发 npmjs。

npm 路径 vs Docker 方案

npm 路径(npx)Docker 镜像(npm 安装路径)
启动耗时npx 首次拉取约 15–20s(闭包 224 包,~290MB 安装体积),之后秒级镜像拉取(压缩,较 npm 路径多一层基础系统),解压 ~0.91GiB
构建耗时无构建(前端 dist 随包分发)镜像构建 = apt 层 + npm install(不再全量编译 monorepo)
内置工具链仅 Node.js(需要 agent 编译环境时用 Docker)Python/gcc·g++/pnpm 内置,Rust 按需(JDK/Go 不内置)
升级npx @deepseek-ai/dsh@alpha web 每次自动拉新重新 build/push/pull 镜像
数据目录$DSH_HOME(默认 ~/.dshdsh-data 卷挂载 /home/dsh/.dsh
适用个人工作站/服务器快速上手、CI服务器常驻部署、离线环境、含原生编译链的 agent 场景

两者共享同一套运行时行为:0.0.0.0 默认绑定、DSH_TRUSTED_HOSTS/DSH_TRUST_ALL、浏览器 token 认证、$DSH_HOME 数据布局。

二、本地构建并运行(Docker)

git clone <仓库地址>
cd DSH
pnpm run build:official                                  # 1. 官方构建(镜像安装的 pack 产物来自这一步)
pnpm run release:pack --family dsh --out dist/npm        # 2. 产出 dist/ pack 产物(vendor/landlock 同理,见上文发布序列)
docker compose build        # 3. 构建镜像:复制 dist/ tarball 进镜像并 npm install(无 monorepo 编译)
docker compose up -d        # 4. 启动
# 从 docker logs dsh 复制带 ?token= 的 dsh web: URL,在浏览器打开(token 换取 30 天签名 cookie)

首次使用时在 Web UI 中配置模型 API Key(DeepSeek 或任意 OpenAI 兼容端点)。

清理 buildx 构建缓存

多架构构建(amd64 + arm64)会把每个大层各存两份,反复改 Dockerfile 后 buildx 不会自动回收被替换的旧层,缓存体积会持续膨胀(可达数十 GB)。构建/推送后定期清理即可回收,不影响已推送的镜像:

docker buildx du --builder multiarch                       # 查看缓存占用
docker buildx prune --builder multiarch --filter until=24h # 只清 24h 前的旧层(推荐)
# 或彻底清空:
# docker buildx prune --builder multiarch --all

三、用云效构建并推送镜像

在云效(Codeup)流水线里配置「镜像构建」步骤(Dockerfile 位于仓库根目录),构建完成后镜像会推送到 ACR(阿里云容器镜像服务)。

随后在目标机器上拉取并运行:

docker pull registry.cn-hangzhou.aliyuncs.com/skymirror/dsh:latest
docker run -d --name dsh \
  -p 0.0.0.0:3080:3080 \
  -v dsh-data:/home/dsh/.dsh \
  -v /path/to/workspace:/workspace \
  -e DSH_HOME=/home/dsh/.dsh \
  registry.cn-hangzhou.aliyuncs.com/skymirror/dsh:latest

四、目录 / 端口映射说明

项目说明
端口 0.0.0.0:3080容器内 dsh web 监听 0.0.0.0:3080
数据卷 dsh-data/home/dsh/.dsh会话记录、settings、storages、agent presets、profiles(插件)、attachments 持久化
./workspace/workspaceagent 的工作目录,编辑宿主机文件实时生效
插件目录 $DSH_HOME/profiles/<name>profile / bundle / cordis.patch.yml 插件的安装位置,位于 dsh-data 卷内持久化
dsh 命令已软链到 /usr/local/bin/dsh,供 docker exec 安装与管理插件
$PNPM_HOME/home/dsh/.dsh/pnpm,pnpm 全局目录落在 dsh-data 卷内,不依赖 /workspace 是否挂载
$DSH_HOME/home/dsh/.dsh,DSH 所有用户数据的根目录
$HOME/workspace,让 Web UI 目录选择器默认从 /workspace 开始浏览

四·五、镜像内置语言运行环境

镜像内已预装以下环境,agent 可直接编写并运行对应代码:

语言/工具版本来源说明
Node.js24.19.0基础镜像含 npm
npm11.17.0npm 全局安装
pnpm11.7.0corepackdsh plugin add 内部依赖,allowBuilds 预置随镜像提供
Python3.11apt(Debian bookworm)预编译、glibc 一致,含 pip/venv/Python.h
Ruststable(按需安装)rustup-init 引导程序首次运行 cargo/rustc/rustup 时自动装进 dsh-data 卷,见下文
gcc / g++12(bookworm 最新)apt编译 C/C++ 及带 C 扩展的 Python 包
git / curlapt供 agent 拉依赖、编译

npm 安装路径镜像不再内置 JDK 17 与 Go 1.26.6(体积优先的取舍,两个工具链合计约 600MB)。需要 Java/Go 的 agent 任务可进容器后自行安装(apt 或官方 tarball),或在此 Dockerfile 基础上按需加回。

云效构建机在香港,网络可直连国际源(npm、PyPI、crates.io、GitHub、Docker Hub 均走官方源,无需镜像)。本地/国内构建仍默认走国内镜像(npmmirror + USTC apt/Rust/pip)。rustup 镜像源已从清华切换到 USTC(清华 rustup 镜像路径已下线)。

构建注意:Python 用 apt 的 python3(3.11,与容器 glibc 一致)而非源码编译;npm install 的 cache 定向 /tmp 并在层内清除,不进镜像层。python/pip 已软链到 /usr/local/bincargo/rustc/rustup 是首次调用自动安装的包装器;dsh 由镜像构建末尾软链到 /usr/local/bin

Rust 按需安装

镜像不内置完整 Rust 工具链(省 ~1GB),只内置 rustup-init 引导程序和 /usr/local/bin/ensure-rust 包装器。首次调用 cargorustcrustup 时,包装器会自动把最小 stable toolchain 装进 $RUSTUP_HOME/home/dsh/.dsh/rustup)和 $CARGO_HOME/home/dsh/.dsh/cargo),两者都在 dsh-data 卷内,重启后保留。toolchain 与 crates 依赖默认走清华镜像(RUSTUP_DIST_SERVER + cargo config.toml 稀疏索引)。首次安装需要容器能访问网络;也可提前手动执行 docker exec dsh cargo --version 触发安装。

五、自定义配置

修改端口

编辑 docker-compose.yml,把 --port 传给容器:

    command: ["--port", "8080"]

或直接改端口映射两侧的值。

从其它机器访问

docker-compose.yml 已把端口映射为 "3080:3080"(宿主机所有接口),容器内 dsh web 默认监听 0.0.0.0:3080。非本机浏览器需要过两道门:

  1. /api 浏览器信任围栏(可达性):DSH_TRUSTED_HOSTS 只信任指定地址(多个用逗号分隔;设置后不再自动信任局域网地址),DSH_TRUST_ALL=1 跳过 Host 校验(仅限可信网络)。
  2. 浏览器认证(身份):从启动日志 docker logs dsh 找到 dsh web: http://…/?token=… 行,把主机名换成服务器地址后在浏览器打开;token 只在根路径有效,成功后写入 30 天签名 cookie,之后正常使用。例外DSH_TRUST_ALL=1 时第 2 步整个跳过——该变量是请求级逃生口,同时跳过围栏与浏览器认证,仅供反向代理已完成全部调用方认证的可信网络使用。
    environment:
      # 方式一(推荐):只信任指定地址,多个用逗号分隔;浏览器仍需 token 引导
      - DSH_TRUSTED_HOSTS=your-server-ip-or-domain
      # 方式二(免配置,跳过围栏+浏览器认证):仅限 NGINX 等已统一认证的可信网络
      # - DSH_TRUST_ALL=1

⚠️ 警告:DSH 具备执行代码能力。DSH_TRUST_ALL=1 会同时关闭防 DNS-rebinding / 跨站请求的 Host 校验与浏览器认证,只能用于上游带认证反向代理的可信内网,切勿裸暴露公网。

ℹ️ 注意:设置页(模型 / API Key 配置)向已认证的远程浏览器开放。浏览器认证统一覆盖所有 /api 方法,远程浏览器完成 token 交换后即可读写模型与 API Key 配置,其设置偏好持久化保存。传输安全与入口认证请在 DSH 前用带认证 / TLS 的反向代理(如 NGINX basic-auth)挡一层,不要把裸端口直接暴露公网。

挂载自己的 .dsh 目录

    volumes:
      - /data/dsh:/home/dsh/.dsh   # 替换命名卷为宿主机目录
      - ./workspace:/workspace

安装与加载外部插件

插件(cordis.yml 插件、bundle、profile)安装在 $DSH_HOME/profiles/<name> 下,位于 dsh-data 卷内,重启后保留。容器内 dsh 已软链到 PATH,可直接执行:

docker exec -it dsh dsh plugin --profile web add github:user/plugin
docker exec -it dsh dsh --profile web

带原生依赖(node-gyp 编译)的插件在安装时编译:镜像运行时已内置 gcc/g++/make/python3/npm/pnpm/git。

第三方插件市场(如 dsh-market)自行维护自己的 pnpm 安装目录,不读 profile 的 allowBuilds 预置,因此带原生依赖的插件(node-pty)会触发 pnpm 的构建脚本拦截——按其提示执行一次 approve-builds(或等效命令)放行 node-pty 即可。它的 catalog/registry 抓取走它自己的默认地址,需要容器能对该地址出网;国内网络无法直连时,要么配置代理,要么让该工具改走可达的镜像源。

六、常见问题

现象处理
构建报内存不足增大 Docker 内存配额
端口被占用修改 docker-compose.yml 端口映射
页面打不开docker logs dsh 看是否打印 dsh web: http://…/?token=…
/api 请求 401(要求认证)浏览器地址未带 token:从 docker logs dsh 复制带 ?token= 的 URL 打开(主机名换成服务器地址)
/api 请求 403非本机访问需设置 DSH_TRUSTED_HOSTS 为你的访问地址(或可信内网设 DSH_TRUST_ALL=1
crypto.randomUUID is not a function老镜像,重新构建(已在上游补丁修复)

评论

推荐阅读

订阅邮件

订阅更新,及时收到最新文章。

作者