🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

容器化部署镜像 soulwhisper/deepseek-harness-container

DeepSeek Harness
soulwhisper9 天前有提交已提供中文文档扫描:含敏感能力

打包 Web 与 Tavern 两套 OCI 镜像,供受控入口后部署

30/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/27 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add soulwhisper/deepseek-harness-container
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么
dsh 原生插件 · tool
装得上吗
本站尚未做安装检查
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 9 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件
查看扫描证据(共 38 处,展示前 36 条)
  • 读取本地文件
    patches/dsh/patch-host.mjs:67
    try { canonical = await realpath(nodeModules); } catch (error) { if (error.code === 'ENOENT') return found; throw error; }
  • 读取本地文件
    patches/dsh/patch-host.mjs:70
    for (const entry of await readdir(nodeModules, { withFileTypes: true })) {
  • 读取本地文件
    patches/dsh/patch-host.mjs:74
    for (const item of await readdir(path, { withFileTypes: true })) if (item.isDirectory()) await packageRoots(join(path, item.name, 'node_modules'), fou
  • 读取本地文件
    patches/dsh/patch-host.mjs:76
    for (const item of await readdir(path)) {
  • 读取本地文件
    patches/dsh/patch-host.mjs:77
    const root = await realpath(join(path, item));
  • 读取本地文件
    patches/dsh/patch-host.mjs:82
    const root = await realpath(path);
  • 写入本地文件
    patches/dsh/patch-host.mjs:111
    for (const [path, content] of pending) await writeFile(path, content);
  • 读取本地文件
    patches/market/patch-market.mjs:32
    const manifest = JSON.parse(await readFile(join(directory, 'package.json'), 'utf8'));
  • 读取本地文件
    patches/market/patch-market.mjs:37
    const source = await readFile(path, 'utf8');
  • 写入本地文件
    patches/market/patch-market.mjs:45
    await writeFile(path, patched);
  • 读取本地文件
    patches/tavern/patch-tavern.mjs:7
    const manifest = JSON.parse(await readFile(join(directory, 'package.json'), 'utf8'));
  • 读取本地文件
    patches/tavern/patch-tavern.mjs:12
    const text = await readFile(join(directory, name), 'utf8');
  • 读取本地文件
    patches/tavern/patch-tavern.mjs:34
    const versions = JSON.parse(await readFile(new URL('../../versions.json', import.meta.url), 'utf8'));
  • 读取本地文件
    patches/tavern/patch-tavern.mjs:38
    await writeFile(file, patchRoutes(await readFile(file, 'utf8'), versions.tavern.routesSha256));
  • 写入本地文件
    patches/tavern/patch-tavern.mjs:38
    await writeFile(file, patchRoutes(await readFile(file, 'utf8'), versions.tavern.routesSha256));
  • 读取本地文件
    patches/wrongbook/patch-mvu-api.mjs:45
    if (!existsSync(target)) return { state: 'missing', target }
  • 读取本地文件
    patches/wrongbook/patch-mvu-api.mjs:46
    return { state: stateOf(readFileSync(target, 'utf8')), target, mtime: statSync(target).mtime }
  • 读取本地文件
    patches/wrongbook/patch-mvu-api.mjs:46
    return { state: stateOf(readFileSync(target, 'utf8')), target, mtime: statSync(target).mtime }
  • 读取本地文件
    patches/wrongbook/patch-mvu-api.mjs:51
    const before = readFileSync(target, 'utf8')
  • 写入本地文件
    patches/wrongbook/patch-mvu-api.mjs:55
    if (backup) copyFileSync(target, `${target}.bak-wrongbook-mvu-api`)
  • 写入本地文件
    patches/wrongbook/patch-mvu-api.mjs:56
    writeFileSync(target, applyText(before), 'utf8')
  • 读取本地文件
    patches/wrongbook/patch-mvu-api.mjs:62
    const before = readFileSync(target, 'utf8')
  • 写入本地文件
    patches/wrongbook/patch-mvu-api.mjs:64
    writeFileSync(target, revertText(before), 'utf8')
  • 读取本地文件
    patches/wrongbook/patch-timeout-body.mjs:86
    if (!existsSync(target)) return { state: 'missing', target }
  • 读取本地文件
    patches/wrongbook/patch-timeout-body.mjs:87
    return { state: stateOf(readFileSync(target, 'utf8')), target }
  • 读取本地文件
    patches/wrongbook/patch-timeout-body.mjs:92
    const before = readFileSync(target, 'utf8')
  • 写入本地文件
    patches/wrongbook/patch-timeout-body.mjs:96
    if (backup) copyFileSync(target, `${target}.bak-wrongbook-timeout-body`)
  • 写入本地文件
    patches/wrongbook/patch-timeout-body.mjs:97
    writeFileSync(target, applyText(before), 'utf8')
  • 读取本地文件
    patches/wrongbook/patch-timeout-body.mjs:103
    const before = readFileSync(target, 'utf8')
  • 写入本地文件
    patches/wrongbook/patch-timeout-body.mjs:105
    writeFileSync(target, revertText(before), 'utf8')
  • 删除本地文件
    plugins/forward-auth/index.mjs:137
    if (ownsPath) try { await unlink(readinessPath); } catch (error) { if (error.code !== 'ENOENT') throw error; }
  • 读取本地文件
    plugins/forward-auth/index.mjs:142
    const existing = await lstat(readinessPath);
  • 删除本地文件
    plugins/forward-auth/index.mjs:144
    await unlink(readinessPath);
  • 写入本地文件
    plugins/forward-auth/index.mjs:150
    await chmod(readinessPath, 0o600);
  • 读取本地文件
    plugins/forward-auth/source.mjs:30
    const info = await stat(archive);
  • 读取本地文件
    plugins/forward-auth/source.mjs:49
    else await pipeline(createReadStream(archive), response);
扫描于 2026/11/4(0 天前) · 范围 全包扫描 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-client-connection@deepseek-ai/dsh-host-webserver
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

README

由 DeepSeek 最新模型翻译生成
DeepSeek Harness Container 面向 已验证 forward-auth 入口之后的单一共享 owner,自行打包的 DeepSeek Harness 发行版。提供两个 OCI 镜像、独立维护的 forward-auth gate、明确的状态/备份边界,不包含桌面栈。 DSH 0.2.1-rc.2 仍是 developer preview,不是经过安全审计的生产平台。登录成功不代表入口、插件、模型凭据、备份或 Agent 沙箱已安全。不要直接暴露原生监听端口。 镜像 | 镜像 | Release 标签 | Profile | | ghcr.io/soulwhisper/dsh-web:0.2.1-rc.2-r2 | web-0.2.1-rc.2-r2 | DSH Web + dshmarket + dsh-context + 必需 forward-auth | | ghcr.io/soulwhisper/dsh-tavern:3.1.3 | tavern-3.1.3 | 自定义 Tavern workspace + forward-auth + 固定且受 manager 保护的配套插件 | Web 镜像使用 distribution revision(DSH 版本不变时以 -rN 区分镜像变更),Tavern 跟随 dsh-tavern;两者独立发版。
展开完整文档(README 剩余 1 节)
DeepSeek Harness Container

面向 已验证 forward-auth 入口之后的单一共享 owner,自行打包的 DeepSeek Harness 发行版。提供两个 OCI 镜像、独立维护的 forward-auth gate、明确的状态/备份边界,不包含桌面栈。

DSH 0.2.1-rc.2 仍是 developer preview,不是经过安全审计的生产平台。登录成功不代表入口、插件、模型凭据、备份或 Agent 沙箱已安全。不要直接暴露原生监听端口。

镜像

| 镜像 | Release 标签 | Profile |
| ghcr.io/soulwhisper/dsh-web:0.2.1-rc.2-r2 | web-0.2.1-rc.2-r2 | DSH Web + dshmarket + dsh-context + 必需 forward-auth |
| ghcr.io/soulwhisper/dsh-tavern:3.1.3 | tavern-3.1.3 | 自定义 Tavern workspace + forward-auth + 固定且受 manager 保护的配套插件 |

Web 镜像使用 distribution revision(DSH 版本不变时以 -rN 区分镜像变更),Tavern 跟随 dsh-tavern;两者独立发版。镜像使用 Node 24/glibc、UID/GID 1000:1000、单一具体 IP 的 3080 监听和只读根文件系统。Web 镜像会 seed 可选的 Caveman、RTK skill,安装 RTK OSS binary,并在可移除的 Web profile 中 seed dsh-context;forward-auth bundle 与 Tavern 固定管理的 bundle 受 manager 保护,Web 浮动插件仍可移除。Tavern 镜像刻意不包含这些浮动资产。这三项上游资产在 Web 镜像构建时取各自最新状态,不在仓库中锁定版本,也不由 Renovate 跟踪;因此部署应使用发布 digest,不能假设从 latest 重建完全可复现。详见 build。CI 在原生 linux/amd64 与 linux/arm64 runner 上构建,不使用 QEMU。镜像不包含 Chromium、GUI、X11、VNC、本地密码库、OIDC 客户端或替代 mux 服务。

文档

| 文档 | 内容 |
| 文档首页 | 阅读路径、镜像与安全摘要 |
| Architecture | 镜像、信任边界、仓库布局 |
| Constraints | 安全与兼容性约束 |
| Build | Docker target、源码载荷、锁文件 |
| Deploy | Compose 与 Kubernetes 示例 |
| Operations | 启动、迁移、备份、回滚 |
| Data layout | 持久状态与 cache/logs/backup/tmp 边界 |
| Patches | 精确哈希上游补丁 |
| Source build | Tavern 对应源码与重建配方 |
| Licensing | Apache/MIT/AGPL 义务 |
| Forward-auth | trusted-edge 认证、状态日志、token URL |

docs/ 仅维护英文文档;根目录中文 README 是本地化入口,不建立第二套文档树。

构建

Build context 是仓库根目录,Dockerfile 为 docker/Dockerfile。

arm64 主机请把 linux/amd64 换成 linux/arm64。
docker buildx build -f docker/Dockerfile --platform linux/amd64 --target web \
--build-arg IMAGE_REVISION="$(git rev-parse HEAD)" --load -t dsh-web:local .
docker buildx build -f docker/Dockerfile --platform linux/amd64 --target tavern \
--build-arg IMAGE_REVISION="$(git rev-parse HEAD)" --load -t dsh-tavern:local .

最终镜像只接收白名单构建/源码输入;test、smoke、deploy、CI 和一般文档不会随镜像发布。修改锁、补丁、源码 commit 或 release tag 前请阅读 build。

运行

生产环境必须使用核验过的 @sha256:… digest,而不是可变 tag。以下为应用侧示例:已验证入口已存在于私网,容器不发布宿主端口。

docker network create --subnet 172.30.80.0/24 dsh-private
docker volume create dsh-web-data
docker volume create dsh-web-workspace
docker volume create dsh-web-cache
docker volume create dsh-web-logs
docker volume create dsh-web-backups

export IMAGE=ghcr.io/soulwhisper/dsh-web:0.2.1-rc.2-r2
export ALLOWED_SUBJECTS='your-stable-owner-id'

docker run --detach --name dsh-web --restart unless-stopped \
--network dsh-private --ip 172.30.80.3 \
--user 1000:1000 --read-only --cap-drop ALL \
--security-opt no-new-privileges:true --pids-limit 512 \
--tmpfs /tmp:rw,nosuid,nodev,mode=1777,size=256m \
--mount type=volume,src=dsh-web-data,dst=/data \
--mount type=volume,src=dsh-web-workspace,dst=/workspace \
--mount type=volume,src=dsh-web-cache,dst=/cache \
--mount type=volume,src=dsh-web-logs,dst=/logs \
--mount type=volume,src=dsh-web-backups,dst=/backups \
--env DSH_HOST=172.30.80.3 \
--env DSH_PUBLIC_URL=https://dsh.example.net \
--env DSH_TRUSTED_HOSTS=dsh.example.net \
--env DSH_FORWARD_AUTH_HEADER=x-authentik-uid \
--env DSH_FORWARD_AUTH_ALLOWED_SUBJECTS="$ALLOWED_SUBJECTS" \
--env DSH_FORWARD_AUTH_TRUSTED_PROXY_CIDRS=172.30.80.2/32 \
"$IMAGE"

访问干净的 HTTPS 入口地址,不要使用启动日志中的 URL。Tavern 应使用独立容器、/data、/workspace、cache/log/backup 根和监听 IP。Compose/Kubernetes 示例见 deploy/,操作细节见 deploy。

状态与备份边界

| 路径 | 策略 |
| /data/dsh | 持久 Profile、sessions、storages、attachments、凭据;加密备份 |
| /data/home | 持久 HOME/XDG/工具状态;备份 |
| /workspace | 持久用户项目;与 /data/dsh 一致快照 |
| /cache | 可重建缓存;$DSH_HOME/cache 指向这里,可丢 |
| /logs | DSH 启动诊断;$DSH_HOME/logs 指向这里,敏感且非权威 |
| /backups | DSH_BACKUP_ROOT 下的迁移回滚副本,不是独立备份 |
| /tmp | 每容器 tmpfs scratch,可能 noexec |
| /opt/dsh、/opt/apps/dsh-tavern | 不可变镜像内容 |

不要把 cache、logs、backup 或 scratch 放回 /data;entrypoint 会把旧的 cache/logs 目录移动一次,并在回滚副本中排除。详见 data layout。

Forward-auth 边界

OAuth/OIDC、登录、MFA、会话校验和访问策略由已验证入口负责,不是镜像内的 OIDC 客户端。入口必须认证每个 HTTP 请求与 WebSocket upgrade,删除客户端提交的身份头,设置唯一、可配置的稳定 subject header,保留公开 Host/Origin,并成为唯一可访问 DSH 的网络 peer。

@soulwhisper/dsh-forward-auth 检查真实 peer CIDR 与 subject allowlist,保护静态资源、源码和原生 manager,并通过 DSH Connection API 换取原生 HttpOnly; SameSite=Strict cookie。header 可配置(Authentik x-authentik-uid、Authelia Remote-User 等);镜像不包含 OIDC client、本地密码、bootstrap admin 或用户面板。认证缺失或失败时路由保持拒绝,不会退回无保护监听。所有允许 subject 共享一个 DSH owner 的文件、工具、模型与凭据,不是多用户隔离。

gate 还会拒绝任何查询字符串包含 token 的请求,包括 upstream DSH launch-token URL 和 WebSocket upgrade。启动日志仍可能包含该 token;必须把容器日志视为敏感数据。状态日志会报告 waiting-for-edge、active、限速的拒绝原因,或固定分类的 broken。详见 forward-auth。

发布与自动化

只有 web-<distribution> 与 tavern-<version> 标签会发布。标签必须匹配 versions.json、位于 main,在原生 amd64/arm64 runner 上构建并 smoke,再合并为一个多架构 index。没有 latest 镜像标签、分支发布或 candidate sha- 镜像;dsh-context、Caveman、RTK 是构建时浮动上游资产,不是发布标签。PR 始终运行必需的静态检查与测试;只有影响镜像/构建输入时才运行原生镜像 smoke;不获取仓库 secrets。同仓库 PR labeler 与定时 label sync 只使用 job 级默认 token(pull-requests: write / issues: write);registry push 使用 job 级 GITHUB_TOKEN + packages: write,release notes 与 cleanup 使用 GitHub App。构建/测试 job 不获取 App 凭据。

Renovate 仅提供提示,从不自动合并。源码 commit、精确补丁/主题哈希、锁和 release tag 必须由人工一起更新。

HA 限制

当前 deployment 是单副本 StatefulSet,/data 和 /workspace 使用 RWO。DSH 的 session 是进程内状态,只有 per-session flock,没有 home 级 leader election,也没有 live-session handoff。不要把副本扩到 2,也不要把共享 RWX home 当作 hot failover。PDB 只保护 voluntary disruption;这是 DSH 的限制,不是 Kubernetes 调参问题。

许可与对应源码

本项目原创代码按 LICENSE 的 Apache-2.0 发布;上游 MIT 声明保存在 NOTICE。Tavern 是 AGPL-3.0-only;修改后的源码与构建配方保留在 Tavern 镜像中,认证用户可通过 /distribution/source.tar.gz 下载对应源码归档。部署时必须保持该源码提供可用;修改或再分发 Tavern 时履行 AGPL 义务。详见 regulations 与 source build。
预览分享卡片长什么样 ↓soulwhisper/deepseek-harness-container
分享 · DeepSeek Harness Hub
soulwhisper/deepseek-harness-container

打包 Web 与 Tavern 两套 OCI 镜像,供受控入口后部署

这是你的仓库?认领条目

回到顶部