Files
DeepSeekHarnessDocker/DEPLOY.md
T
SKYMirror 4be0850529 docs: add docker / docker-compose run examples
Document ACR multi-arch image, compose minimal YAML, docker run
variants (pin version, custom port, --trusted-host), and token URL
handling.
2026-09-16 01:29:11 +08:00

11 KiB
Raw Blame History

DeepSeek Harness Docker 部署

本仓库只包含 Docker 部署封装,不含 DSH 源码。运行时从 npm 安装官方 @deepseek-ai/dsh。

构建产出 工具链底座(Node 24 / Python 3.11 / gcc / pnpm / rustup 引导),约 750MB(arm64 实测)
每次启动 npm install -g @deepseek-ai/dsh@latest,失败则容器退出(无内置 dsh 兜底)
宿主机端口 3080
数据 命名卷 dsh-data → /home/dsh/.dsh(会话、设置、插件、npm cache)

快速开始

git clone <本仓库地址>
cd DSH
docker compose up -d --build
docker logs -f dsh

日志中会出现:

dsh-entry: installed 0.1.5-rc.1          ← 版本以 npm 上 latest 为准
dsh-entry: forwarding 0.0.0.0:3080 -> 127.0.0.1:3081
dsh web: http://127.0.0.1:3081/?token=<一次性令牌>
  1. 把 URL 里的 127.0.0.1:3081 换成 127.0.0.1:3080(或 服务器IP:3080)
  2. 浏览器打开一次带 ?token= 的地址 → 写入 30 天 cookie
  3. 之后直接访问 http://127.0.0.1:3080/ 即可

国内网络建议在 docker-compose.yml 的 environment 中启用:

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

官方 @latest 强制浏览器认证,没有免 token 开关。DSH_TRUST_ALL 只存在于历史 fork 镜像,当前路径无效。

运行示例

已推送镜像(多架构 linux/amd64 + linux/arm64):

registry.cn-hangzhou.aliyuncs.com/skymirror/dsh:latest

1. Docker Compose(推荐,本仓库源码构建)

git clone <本仓库地址>
cd DeepSeekHarnessDocker

# 国内网络:取消注释 docker-compose.yml 里的 DSH_NPM_REGISTRY
#   - DSH_NPM_REGISTRY=https://registry.npmmirror.com

docker compose up -d --build
docker compose logs -f dsh

常用 compose 子命令:

docker compose ps                 # 状态
docker compose logs -f dsh        # 跟日志(找 token URL)
docker compose restart dsh        # 改完插件/配置后重启
docker compose down               # 停容器,保留 dsh-data 卷
docker compose down -v            # 连数据卷一起删(慎用)
docker compose build --no-cache   # 强制重建镜像

完整 docker-compose.yml 可参考仓库内文件;最小可用示例:

services:
  dsh:
    image: registry.cn-hangzhou.aliyuncs.com/skymirror/dsh:latest
    # 或本地构建:build: .
    ports:
      - "3080:3080"
    volumes:
      - dsh-data:/home/dsh/.dsh
      - ./workspace:/workspace
    environment:
      - DSH_HOME=/home/dsh/.dsh
      - HOME=/workspace
      - DSH_NPM_REGISTRY=https://registry.npmmirror.com
    # 远程用 IP 访问时打开(仍需 token cookie):
    # command: ["--trusted-host", "your-server-ip"]
    restart: unless-stopped

volumes:
  dsh-data:

2. Docker Compose(直接用 ACR 预构建镜像,不 build)

mkdir -p dsh-docker && cd dsh-docker
# 把上面的 docker-compose.yml 存到当前目录后:
docker compose up -d
docker compose logs -f dsh

或一行拉起(无 compose):

docker pull registry.cn-hangzhou.aliyuncs.com/skymirror/dsh:latest

docker run -d --name dsh \
  --restart unless-stopped \
  -p 3080:3080 \
  -v dsh-data:/home/dsh/.dsh \
  -v "$PWD/workspace":/workspace \
  -e DSH_HOME=/home/dsh/.dsh \
  -e HOME=/workspace \
  -e DSH_NPM_REGISTRY=https://registry.npmmirror.com \
  registry.cn-hangzhou.aliyuncs.com/skymirror/dsh:latest

docker logs -f dsh

打开日志中的 URL(把 :3081 换成 :3080)。

3. docker run 变体

钉住 dsh 版本(可复现):

docker run -d --name dsh \
  -p 3080:3080 \
  -v dsh-data:/home/dsh/.dsh \
  -e DSH_DIST_TAG=0.1.5-rc.1 \
  -e DSH_NPM_REGISTRY=https://registry.npmmirror.com \
  registry.cn-hangzhou.aliyuncs.com/skymirror/dsh:latest

改宿主机端口(例如 18080):

docker run -d --name dsh \
  -p 18080:18080 \
  -v dsh-data:/home/dsh/.dsh \
  -e DSH_FORWARD_PORT=18080 \
  registry.cn-hangzhou.aliyuncs.com/skymirror/dsh:latest

其它机器通过服务器 IP 访问:

docker run -d --name dsh \
  -p 3080:3080 \
  -v dsh-data:/home/dsh/.dsh \
  -e DSH_NPM_REGISTRY=https://registry.npmmirror.com \
  registry.cn-hangzhou.aliyuncs.com/skymirror/dsh:latest \
  --trusted-host 203.0.113.10

浏览器仍须先用日志里带 ?token= 的 http://203.0.113.10:3080/?token=… 打开一次。

前台调试(不 detach):

docker run --rm -it \
  -p 3080:3080 \
  -v dsh-data:/home/dsh/.dsh \
  -e DSH_NPM_REGISTRY=https://registry.npmmirror.com \
  registry.cn-hangzhou.aliyuncs.com/skymirror/dsh:latest

4. 进入容器

docker exec -it dsh sh
docker exec -it dsh dsh --version
docker exec -it dsh dsh plugin --profile web list

端口拓扑

官方 dsh web 只监听 127.0.0.1,并拒绝 --host 0.0.0.0。Docker -p 打不到容器内 loopback,因此 entrypoint 做 L4 转发:

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

不要单独 -p 映射容器内 3081;Docker 映射的应是转发口 3080。

配置参考

环境变量(entrypoint)

变量 默认 说明
DSH_PACKAGE @deepseek-ai/dsh npm 包名
DSH_DIST_TAG latest dist-tag 或精确版本(如 0.1.5-rc.1)
DSH_NPM_REGISTRY https://registry.npmjs.org 安装用 registry
DSH_NPM_CACHE $DSH_HOME/npm-cache npm cache(卷内,加速重启)
DSH_INTERNAL_PORT 3081 dsh 监听端口(仅 loopback)
DSH_FORWARD_PORT 3080 0.0.0.0 转发端口;与 compose ports 一致

传给 dsh web 的参数

entrypoint 固定执行:

dsh web --no-open --port $DSH_INTERNAL_PORT <compose command...>

compose 的 command 会追加在后面。常用:

# 从其它机器用 IP/域名访问时,声明 Host/Origin 围栏权威(仍需 token cookie)
command: ["--trusted-host", "203.0.113.10"]
不要通过 command 传 原因
--host 0.0.0.0 官方明确拒绝
--port 用 DSH_INTERNAL_PORT
--no-open entrypoint 已固定

改端口

    environment:
      - DSH_FORWARD_PORT=8080
    ports:
      - "8080:8080"

持久化与工作区

    volumes:
      - dsh-data:/home/dsh/.dsh     # 会话/设置/插件(保留)
      - ./workspace:/workspace       # agent 工作目录;HOME 指向这里

插件装在 $DSH_HOME/profiles/<name>/,在卷内,重启不丢:

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

从其它机器访问

  1. 围栏:Host 为 http://<IP>:3080 时不是 loopback,需
    command: ["--trusted-host", "<IP或域名>"]
  2. 认证:仍须用日志里的 ?token= URL 打开一次
  3. 安全:DSH 可执行代码。公网请前置带认证/TLS 的反向代理,不要裸暴露

前置条件

  • Docker Engine 20.10+(BuildKit)
  • Docker Compose v2
  • 容器启动时能访问所配置的 npm registry

构建说明

docker compose build          # 只装 apt/工具链,无 monorepo 编译
docker compose up -d

基础镜像

默认 ARG BASE_IMAGE=registry.cn-hangzhou.aliyuncs.com/skymirror/node:24.19.0-bookworm-slim(与 Docker Hub node:24.19.0-bookworm-slim 同源)。Docker Hub 不可达时可继续用该 ACR 地址,或自建同步后:

docker buildx build \
  --build-arg BASE_IMAGE=<你的registry>/node:24.19.0-bookworm-slim \
  --platform linux/arm64 -t dsh:local --load .

构建源(国内默认)

组件 默认源
apt 清华 Debian
npm(构建期 npm/pnpm) npmmirror
rustup 引导 USTC / rsproxy
pip 清华

可用 --build-arg NPM_REGISTRY=...、APT_MIRROR=... 覆盖。

清理 buildx 缓存

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

镜像内置环境

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

不内置 JDK、Go。需要时进容器安装。

# 预触发 Rust 安装(可选)
docker exec dsh cargo --version

不用 Docker

# Node ^22.19 || >=24
npx --yes @deepseek-ai/dsh@latest web
npm view @deepseek-ai/dsh dist-tags

本机只监听 127.0.0.1,打开日志中的 ?token= URL。插件管理需 corepack enable pnpm。

npx 本仓库 Docker
工具链 仅本机 Node Python / gcc / pnpm / Rust 按需
升级 每次 @latest 每次容器启动 @latest
数据 ~/.dsh dsh-data 卷
远程访问 仅 loopback 3080 转发进容器

仓库布局

Dockerfile              工具链镜像 + entrypoint
docker-compose.yml      端口 / 卷 / 环境变量
docker/entrypoint.sh    安装 @latest → 转发 → dsh web
docker/ensure-rust.sh   Rust 按需安装包装器
DEPLOY.md               本文档
LICENSE                 GPL-3.0

常见问题

现象 处理
启动慢或立刻退出 docker logs:多半 npm 安装失败。设 DSH_NPM_REGISTRY=https://registry.npmmirror.com,或钉版本 DSH_DIST_TAG=0.1.5-rc.1
authentication required; reopen the URL printed by dsh web 正常。用带 ?token= 的 URL 打开一次;官方包不能免 token
GET / 返回 401 同上
/api 返回 403 Host 不在围栏:command: ["--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 官方限制。不要传该参数,依赖转发
端口占用 同时改 ports 与 DSH_FORWARD_PORT
Cannot find module .../dsh/lib/bin.js 覆盖了 entrypoint:/command:,绕过了安装入口;去掉覆盖后重建
插件重启后消失 确认插件装在 $DSH_HOME/profiles,且 dsh-data 卷未挂错
设置了 DSH_TRUST_ALL=1 仍要 token 预期行为。官方包无此变量

许可

本仓库部署封装为 GPL-3.0。上游 DeepSeek Harness 为 MIT,运行时安装的官方 npm 包不受本仓库许可证变更影响。