Files
DeepSeekHarnessDocker/DEPLOY.md
T
SKYMirror 0bfe0b4a65 chore: strip monorepo; keep Docker runtime deploy for official dsh@latest
Image installs @deepseek-ai/dsh from npm on start. Fork 0.1.2-alpha.2 source
is obsolete for this deployment path.
2026-09-16 00:18:32 +08:00

12 KiB
Raw Blame History

DeepSeek Harness (DSH) Docker 部署指南

概述

本仓库是 DeepSeek Harness 源码 + Docker 构建配置。镜像只内置工具链,不把 dsh 钉死在构建层:容器每次启动由 docker/entrypoint.sh 从 npm 安装官方 @deepseek-ai/dsh@latest(可用环境变量覆盖),安装失败则非零退出,不回退到旧版本。因此启动时必须能访问 npm registry。

端口拓扑(当前实现)

官方 dsh web 只监听 127.0.0.1,并明确拒绝 --host 0.0.0.0(安全原因:Web 面可远程执行代码)。Docker 的 -p 打不到容器内 loopback,故 entrypoint 额外起一层 L4 转发:

宿主机 :3080  →  容器 0.0.0.0:3080  →  127.0.0.1:3081 (dsh web --no-open --port 3081)
┌──────────┐  http://localhost:3080/?token=…  ┌─────────────────────────────┐
│ 浏览器    │ ────────────────────────────────▶ │  0.0.0.0:3080  (转发)       │
└──────────┘                                  │       ↓                      │
                                              │  127.0.0.1:3081 (dsh web)   │
                                              └──────────────┬──────────────┘
                              ┌──────────────────────────────┼──────────────┐
                              │ dsh-data 卷                   │ ./workspace  │
                              │ /home/dsh/.dsh                │ /workspace   │
                              │ (会话/设置/插件/配置)            │ (工作目录)    │
                              └──────────────────────────────┴──────────────┘

浏览器认证(官方包行为)

官方 @latest 强制浏览器认证,没有免 token 的开关:

  1. 从 docker logs 复制带 ?token= 的 URL,用浏览器打开一次
  2. 服务端 303 下发 30 天签名 cookie
  3. 之后同一浏览器直接访问 http://<host>:3080/ 即可

说明:历史 fork 镜像里的 DSH_TRUST_ALL=1、DSH_TRUSTED_HOSTS 环境变量、默认绑定 0.0.0.0 均不在官方 npm 包中。官方侧 Host/Origin 围栏可用 --trusted-host(compose command 传入)扩展非 loopback 权威;cookie 认证仍必须完成。

镜像信息

当前 Dockerfile 为「运行时拉取」模型:构建产出工具链底座(约 747MB,linux/arm64 本地实测),dsh 版本由每次容器启动时的 @deepseek-ai/dsh@latest 决定,不体现在镜像 tag 里。

项目 值
基础镜像 registry.cn-hangzhou.aliyuncs.com/skymirror/node:24.19.0-bookworm-slim(ARG BASE_IMAGE 可覆盖;内容同 docker.io/library/node:24.19.0-bookworm-slim)
dsh 安装 启动时 npm install -g @deepseek-ai/dsh@latest(默认 registry.npmjs.org)
宿主机端口 3080(compose 3080:3080)
容器内 dsh 端口 3081(仅 127.0.0.1)
ENTRYPOINT /usr/local/bin/dsh-entrypoint

历史镜像存档(已过时,勿按其行为部署)

以下 digest 对应旧 fork 构建时安装镜像(0.1.2-alpha.2-skymirror.1,dist/ pack + file: 闭包、DSH_TRUST_ALL、默认 0.0.0.0)。当前 Dockerfile 已取代该模型,哈希仅备查:

项目 值
manifest list sha256:4c8636d1f20804a39757829de5adb27dccf6435b99610e2a70e74fe8cc95b5bd
更早 monorepo 编译镜像 sha256:8a5d6406abd56f5cc3f175aa6b751e226bc91430dfb896add1fcf9a3f970f39e

快速开始

git clone <仓库地址>
cd DSH
docker compose build
docker compose up -d
docker logs -f dsh
# 等待出现类似:
#   dsh-entry: installed 0.1.5-rc.1
#   dsh-entry: forwarding 0.0.0.0:3080 -> 127.0.0.1:3081
#   dsh web: http://127.0.0.1:3081/?token=<一次性令牌>
# 把日志 URL 中的 127.0.0.1:3081 换成 127.0.0.1:3080(或服务器 IP:3080)后打开

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

国内网络建议在 compose 的 environment 里加:

- DSH_NPM_REGISTRY=https://registry.npmmirror.com

启动环境变量与参数

环境变量(docker/entrypoint.sh)

变量 默认 说明
DSH_PACKAGE @deepseek-ai/dsh 要安装的包名
DSH_DIST_TAG latest npm dist-tag 或精确版本(如 0.1.5-rc.1)
DSH_NPM_REGISTRY https://registry.npmjs.org 拉包 registry;国内可设 https://registry.npmmirror.com
DSH_NPM_CACHE $DSH_HOME/npm-cache npm cache(dsh-data 卷内,重启可命中)
DSH_INTERNAL_PORT 3081 dsh 监听端口(仅 127.0.0.1)
DSH_FORWARD_PORT 3080 entrypoint 在 0.0.0.0 上的转发端口(Docker -p 应映射此端口)

传给 dsh web 的参数

entrypoint 固定附加 --no-open --port ${DSH_INTERNAL_PORT}。compose 的 command 会追加在后面,例如:

    command: ["--trusted-host", "203.0.113.10"]
参数 作用
--trusted-host <authority> 向 Host/Origin 围栏追加非 loopback 权威(可重复);不替代 cookie 认证
--port / --host 不要通过 command 覆盖:端口由 DSH_INTERNAL_PORT 管理;--host 0.0.0.0 会被官方拒绝

前置条件

  • Docker Engine 20.10+(BuildKit)
  • Docker Compose v2
  • 启动时能访问 npm registry(官方 npmjs 或 npmmirror)

一、不用 Docker 直接跑

# Node.js ^22.19 || >=24
npx --yes @deepseek-ai/dsh@latest web
# 或
npm install -g @deepseek-ai/dsh@latest
dsh web --no-open --port 3080

本机默认只监听 127.0.0.1,浏览器打开日志里的 ?token= URL。管理插件需要 corepack enable pnpm。

查看可用版本:

npm view @deepseek-ai/dsh dist-tags

npm 路径 vs Docker

npx @latest Docker(本仓库)
启动耗时 首次拉包约 15s–数分钟(视网络/cache) 镜像已有工具链;每次启动装 dsh(有 cache 更快)
构建 无 只装 apt/工具链,不编译 monorepo
工具链 仅本机 Node Python / gcc·g++ / pnpm / Rust 按需
升级 每次 npx@latest 每次容器启动装 @latest(失败退出)
数据 $DSH_HOME(默认 ~/.dsh) dsh-data → /home/dsh/.dsh
远程端口 只听 loopback entrypoint 3080 → dsh 3081

二、本地构建并运行

docker compose build
docker compose up -d

构建不需要 pnpm build、release:pack 或 dist/。

基础镜像拉不动时

Docker Hub 在部分网络不可达。可先把官方 node 镜像同步到自己 registry,再:

docker buildx build \
  --build-arg BASE_IMAGE=registry.cn-hangzhou.aliyuncs.com/skymirror/node:24.19.0-bookworm-slim \
  --platform linux/arm64 \
  -t dsh:local-arm64 --load .

清理 buildx 缓存

docker buildx du
docker buildx prune --filter until=24h
# 或
docker buildx prune --all

三、云效构建并推送

流水线「镜像构建」使用仓库根目录 Dockerfile,推送到 ACR。目标机:

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

注意:推上去的是工具链底座;运行时仍会拉 npm 上的 dsh。请保证部署机可访问所配置的 registry。

四、目录 / 端口映射

项目 说明
宿主机 3080 → 容器 3080 entrypoint 的 0.0.0.0 转发口
容器内 dsh 3081 仅 127.0.0.1,不要单独 -p 映射
dsh-data → /home/dsh/.dsh 会话、settings、storages、profiles(插件)、npm-cache
./workspace → /workspace agent 工作目录;目录选择器默认起点(HOME)
$DSH_HOME/profiles/<name> 插件与 profile,卷内持久化
dsh 命令 启动时 npm install -g 装入 PATH,供 docker exec 管理插件

插件示例:

docker exec -it dsh dsh plugin --profile web add <package>
# 改完插件需重启容器
docker restart dsh

五、镜像内置语言环境

语言/工具 版本 说明
Node.js 24.19.0 基础镜像
npm 11.17.0 全局升级
pnpm 11.7.0 corepack;dsh plugin add 使用
Python 3.11 apt,含 pip/venv/Python.h
Rust stable 按需 首次调用 cargo/rustc/rustup 时装进 dsh-data 卷
gcc / g++ / make bookworm 原生模块编译
git / curl apt

不内置 JDK、Go(体积取舍)。需要时进容器自行安装。

构建默认走国内源:npm npmmirror、Debian 清华、rustup USTC、pip 清华。云效等可出网环境可用 --build-arg NPM_REGISTRY=... 等覆盖。

Rust 按需安装

/usr/local/bin/ensure-rust 包装器在首次调用时把 toolchain 装进 $RUSTUP_HOME / $CARGO_HOME(均在 dsh-data 卷)。可提前 docker exec dsh cargo --version 触发。

六、自定义配置

修改端口

    environment:
      - DSH_FORWARD_PORT=8080   # 容器 0.0.0.0 转发口
      - DSH_INTERNAL_PORT=3081  # dsh 本机端口(一般不用改)
    ports:
      - "8080:8080"

从其它机器访问

  1. Host/Origin 围栏:浏览器地址为 http://<服务器IP>:3080 时,Host 不是 loopback,需在 compose 中追加:

        command: ["--trusted-host", "<服务器IP或域名>"]
    
  2. 浏览器认证:仍必须用日志里的 ?token= URL 打开一次,换 30 天 cookie。

  3. 传输与入口:DSH 可执行代码。公网暴露请在前面加带认证/TLS 的反向代理,不要裸奔。

挂载自己的数据目录

    volumes:
      - /data/dsh:/home/dsh/.dsh
      - /data/work:/workspace

七、常见问题

现象 处理
启动很慢或退出 看 docker logs:多半是装 @latest 网络失败;设 DSH_NPM_REGISTRY=https://registry.npmmirror.com
authentication required; reopen the URL printed by dsh web 正常:用带 ?token= 的 URL 打开一次;官方包不能免 token
GET / 401 同上
/api 403 Host 不在围栏内:给 dsh web 加 --trusted-host <你的Host>
宿主机 3080 连不上 / connection reset 确认映射的是转发口 3080:3080,且 logs 有 forwarding 0.0.0.0:3080 -> 127.0.0.1:3081
--host 0.0.0.0 is intentionally not supported 官方限制;不要传 --host 0.0.0.0,依赖 entrypoint 转发
端口被占用 改 compose 的 ports 与 DSH_FORWARD_PORT
Cannot find module .../dsh/lib/bin.js 自定义了 entrypoint:/command: 绕过安装入口;去掉覆盖后重建
插件重启后消失 插件应装在 $DSH_HOME/profiles(卷内);确认未挂错卷
设置了 DSH_TRUST_ALL=1 仍要 token 预期行为:官方包无此变量;历史 fork 镜像才有

附录:fork 私有 npm 发布(可选,当前 Docker 不用)

当前 Docker 路径只消费官方 npm @latest。若仍需维护 skymirror fork 并发到私有 registry,可继续用仓库内 release 脚本(与镜像构建解耦):

pnpm run release:dsh <version>
pnpm run build:official
pnpm run release:pack --family dsh --out dist/npm
# … vendor / landlock / verify / publish,见 scripts/release/

fork 的 DSH_TRUST_ALL、DSH_TRUSTED_HOSTS 环境变量、默认 0.0.0.0 绑定等部署补丁只存在于 fork 编译产物中;要在容器里用它们,需把 DSH_PACKAGE / DSH_DIST_TAG / DSH_NPM_REGISTRY 指到私有 registry 的 fork 包,并自行承担与官方 @latest 的行为差异。