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.
This commit is contained in:
commit
0bfe0b4a65
11 files changed
+638
No files matched your search
@@ -0,0 +1,285 @@
|
||||
# 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` |
|
||||
|
||||
## 快速开始
|
||||
|
||||
```bash
|
||||
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` 里加:
|
||||
|
||||
```yaml
|
||||
- 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` 会**追加**在后面,例如:
|
||||
|
||||
```yaml
|
||||
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 直接跑
|
||||
|
||||
```bash
|
||||
# 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`。
|
||||
|
||||
查看可用版本:
|
||||
|
||||
```bash
|
||||
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` |
|
||||
|
||||
## 二、本地构建并运行
|
||||
|
||||
```bash
|
||||
docker compose build
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
构建不需要 `pnpm build`、`release:pack` 或 `dist/`。
|
||||
|
||||
### 基础镜像拉不动时
|
||||
|
||||
Docker Hub 在部分网络不可达。可先把官方 node 镜像同步到自己 registry,再:
|
||||
|
||||
```bash
|
||||
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 缓存
|
||||
|
||||
```bash
|
||||
docker buildx du
|
||||
docker buildx prune --filter until=24h
|
||||
# 或
|
||||
docker buildx prune --all
|
||||
```
|
||||
|
||||
## 三、云效构建并推送
|
||||
|
||||
流水线「镜像构建」使用仓库根目录 `Dockerfile`,推送到 ACR。目标机:
|
||||
|
||||
```bash
|
||||
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` 管理插件 |
|
||||
|
||||
插件示例:
|
||||
|
||||
```bash
|
||||
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` 触发。
|
||||
|
||||
## 六、自定义配置
|
||||
|
||||
### 修改端口
|
||||
|
||||
```yaml
|
||||
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 中追加:
|
||||
|
||||
```yaml
|
||||
command: ["--trusted-host", "<服务器IP或域名>"]
|
||||
```
|
||||
|
||||
2. **浏览器认证**:仍必须用日志里的 `?token=` URL 打开一次,换 30 天 cookie。
|
||||
|
||||
3. **传输与入口**:DSH 可执行代码。公网暴露请在前面加带认证/TLS 的反向代理,不要裸奔。
|
||||
|
||||
### 挂载自己的数据目录
|
||||
|
||||
```yaml
|
||||
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 脚本(与镜像构建解耦):
|
||||
|
||||
```bash
|
||||
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` 的行为差异。
|
||||
Reference in new issue
Block a user