Skip to content

Repository files navigation

dsh-dockeer

将 npm 上的 deepseek-ai/deepseek-harnessdsh)打包为 Docker 镜像并发布到 GitHub Container Registry,供服务器直接运行。

方案npm install -g @deepseek-ai/dsh + 内置 Python loopback proxy。dsh 监听 127.0.0.1(天然通过 trusted-host 检查),proxy 监听 0.0.0.0 并改写 Host 头——无需 --network host、无需 TRUSTED_HOSTS、无需反代透传 Host,普通 -p 端口映射即可外部访问。

文件说明

文件 作用
Dockerfile 两阶段构建:builder 编译 node-pty 原生依赖 → runtime 仅拷贝结果 + python3
loopback-proxy.py TCP 转发代理:0.0.0.0:PORT127.0.0.1:DSH_PORT,改写 Host 头为 loopback
entrypoint.sh 后台启动 dsh → 等就绪 → 前台启动 proxy
.github/workflows/docker.yml GitHub Action:自动构建并推送镜像到 ghcr.io
docker-compose.yml 服务器部署示例

工作流触发方式

  • push 到 main/master(修改了构建相关文件时自动触发)
  • 每天定时(UTC 19:00 / 北京时间凌晨 3:00):检查 @deepseek-ai/dsh@latest 是否有新版本;该版本已构建过则自动跳过
  • 手动触发(workflow_dispatch):可指定 dsh_version(默认 latest)和 platforms

镜像标签:latest / dsh-<npm版本号> / YYYYMMDD

使用方法

推送本仓库到 GitHub 后 Action 自动构建。构建完成后在仓库 Packages 页面可见镜像(建议设为 Public)。

docker run -d \
  --name dsh-web \
  -p 8080:8080 \
  -v /opt/dsh/data:/data \
  -v /opt/dsh/workspace:/workspace \
  --restart unless-stopped \
  ghcr.io/<你的用户名>/dsh-dockeer:latest

或使用 docker-compose(改好镜像地址后 docker compose up -d)。

浏览器打开 http://<服务器IP>:8080 即可使用——不会 403

修改端口

docker run -d -p 9000:8080 -e PORT=8080 ...  # 宿主机 9000 → 容器 8080
#
docker run -d -p 8080:8080 -e PORT=8080 ...  # 默认

PORT 是容器内 proxy 的监听端口,需与 -p 右边一致。DSH_PORT(默认 18080)是 dsh 内部端口,一般不需要改。

传递额外启动参数

容器附加参数会原样追加在 dsh web 命令末尾:

docker run ... ghcr.io/<你的用户名>/dsh-dockeer:latest --some-flag

原理:为什么不会 403

dsh 的 /api 层校验请求头里的 Host / Origin authority,非 loopback 返回 403。上游源码中 --trusted-host 被故意钉死不生效(discussion #128 确认:只有 Host 为 localhost 才能通过检查,127.0.0.1 都不行)。本镜像用 Python TCP 代理绕过:

浏览器 → 0.0.0.0:8080 (proxy) ──TCP──→ 127.0.0.1:18080 (dsh)
                ↓ 改写 HTTP 头
          Host:      localhost:18080
          Origin:    http://localhost:18080
          Referer:   http://localhost:18080/...
          dsh 看到的永远是 localhost 回环 → 通过检查
  • dsh 监听 127.0.0.1:18080,不暴露给外部
  • Python proxy 监听 0.0.0.0:8080,TCP 级别转发,改写三个头:
    • Hostlocalhost:18080(核心,通过 trusted-host 围栏)
    • Originhttp://localhost:18080(浏览器 POST/PUT 请求会发,dsh 也校验)
    • Refererhttp://localhost:18080/...(保留 path,只替换 origin 部分)
  • 强制 Connection: close(避免 keep-alive 后续请求头不被改写)
  • 响应数据原样透传(包括 SSE/chunked 流式输出)
  • 纯标准库,零依赖

⚠️ proxy 只是让 dsh 以为请求来自 localhost,不是访问控制。外部鉴权由调用方负责(防火墙规则、反代加认证等)。

数据持久化

dsh 的全部状态在 $DSH_HOME(默认 ~/.dsh)。本镜像固定 DSH_HOME=/data务必挂载 /data

路径 内容
/data/settings.yaml 模型路由设置(Settings → Models 页面写入)
/data/.credentials.yaml API 密钥(Models 页面写入,UI 不可回读)
/data/.env 环境变量层
/data/profiles/ profile 目录(含 cordis.patch.yml 与插件)
/data/storages/ 会话与工作区状态

Workspace

镜像在 /workspace 启动 dsh,因此默认 workspace root 就是 /workspace。首次使用 Web UI 时点击 Choose workspace 添加并选中 /workspace

API 密钥两种方式:环境变量 DEEPSEEK_API_KEY(优先级最高)或 Web UI Settings → Models 填写。

本地构建

docker build -t dsh:local .                                  # 跟踪 npm latest
docker build --build-arg DSH_VERSION=0.1.0-rc.6 -t dsh:local # 锁定版本
docker run --rm -p 8080:8080 dsh:local

注意事项

  • 镜像约 1.3~1.6 GB:node:24-slim + dsh 依赖树(~1 GB)+ python3(~15 MB)。
  • 原生依赖:dsh 依赖 node-pty,npm 包未附带 linux-x64 预编译产物,builder 阶段用 python3/make/g++ 编译,工具链不进入最终镜像。
  • proxy 限制:TCP 转发 + Connection: close,不支持 WebSocket(dsh 生产环境不需要 HMR);每个 HTTP 请求新建 TCP 连接,对 dsh 使用场景无影响。改写 LOOPBACK_HOST 环境变量可切换回环主机名(默认 localhost,如上游修复后可改为 127.0.0.1)。
  • 上游处于 developer preview,可能存在破坏性变更;重要环境用 dsh-<version> 标签锁定。
  • Action 使用内置 GITHUB_TOKEN 推送 GHCR,无需配置 secret。

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages