<div align="center">

<img src="assets/logo.png" width="128" alt="dsh-vps 标志">

# dsh-vps

<p><strong>把 DeepSeek Harness 装进你的 VPS：一条命令，公网可达，界面原样</strong></p>
<p><strong>Your DeepSeek Harness on your own VPS — one command, reachable from anywhere, native UI intact</strong></p>

<p>
  <a href="LICENSE"><img src="https://img.shields.io/github/license/AIcivilization/dsh-vps" alt="MIT 许可证"></a>
  <a href="https://www.npmjs.com/package/dsh-vps"><img src="https://img.shields.io/npm/v/dsh-vps" alt="npm 版本"></a>
  <img src="https://img.shields.io/badge/platform-Ubuntu%2022.04%2B%20%2F%20Debian%2012%2B-blue" alt="平台：Ubuntu 22.04+ / Debian 12+">
  <img src="https://img.shields.io/badge/DeepSeek%20Harness-%E5%AE%98%E6%96%B9%E6%9C%80%E6%96%B0%E7%89%88-4176E6" alt="DeepSeek Harness 官方最新版">
  <img src="https://img.shields.io/badge/runtime%20dependencies-0-brightgreen" alt="运行时依赖：0">
  <img src="https://img.shields.io/badge/Docker-not%20required-orange" alt="无需 Docker">
  <img src="https://img.shields.io/github/stars/AIcivilization/dsh-vps?style=social" alt="star">
  <a href="https://awesome-dsh-plugin.com/p/AIcivilization/dsh-vps/"><img src="https://img.shields.io/badge/Listed_on-awesome--dsh--plugin-1677ff?style=flat-square" alt="已收录于 awesome-dsh-plugin"></a>
  <a href="https://dshget.com/plugins/AIcivilization/dsh-vps"><img src="https://img.shields.io/badge/Listed_on-DSH_Get-1677ff?style=flat-square" alt="已收录于 DSH Get"></a>
</p>

<p><strong>简体中文</strong> · <a href="README.en.md">English</a></p>

</div>

---

> **这是 DSH 的 VPS 部署工具：把带登录界面的原版 DSH 装到你自己的 VPS 上，之后在任何地方用浏览器访问。** 两种装法任选其一：

**① 在自己电脑上的 DSH 里填表安装**：插件市场搜索 `dsh-vps` 安装（或执行 `dsh plugin add dsh-vps`），打开「设置 → VPS 部署」，填服务器 IP、SSH 端口、用户名，选登录方式（密码 / 私钥 / 本机密钥），有域名再填域名，点「安装到这台 VPS」。

**② 在 VPS 上执行一键安装命令**：

```bash
curl -fsSL https://raw.githubusercontent.com/AIcivilization/dsh-vps/main/install.sh | sudo bash -s
```

有域名、在国内网络时，在末尾追加参数，例如 `bash -s -- --domain dsh.example.com --mirror cn`，详见下方[安装](#安装)。

---

## 简介

[DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)（DSH）默认只认本机浏览器：它的特权接口（设置、API Key、插件管理）受浏览器信任围栏保护，直接反代到公网后这些页面全部失效。

dsh-vps 用一个零运行时依赖的登录网关（dsh-gate）架在 DSH 前面：公网请求先过 scrypt 登录门，再由网关以服务端身份完成 DSH 会话认证并透传。你在任何地方打开浏览器，用的都是官方原版的 DSH Web 界面，设置、模型、API Key、插件市场该有的都有。

DeepSeek Harness (DSH) trusts the operator's own browser only: its privileged interfaces — settings, API keys, plugin management — sit behind a browser-trust fence, and a plain reverse proxy to the public internet leaves those pages dead.

dsh-vps puts a zero-dependency login gateway (dsh-gate) in front of DSH: public requests pass a scrypt login gate first, then the gateway performs DSH session authentication server-side and proxies the rest. You open a browser anywhere and get the stock DSH web interface — settings, models, API keys and the plugin marketplace all working.

---

## 能力一览

| 能力 | 说明 |
| --- | --- |
| 两种装法 | 在自己电脑上的 DSH 里填表、点一下安装（Mac / Windows / Linux）；或在 VPS 上执行一条 `curl \| bash`。装完即 systemd 托管、开机自启 |
| 登录门 | scrypt 口令 + HMAC 会话 Cookie + 登录限流；「保持登录」默认勾选，30 天内免登录；「设置 → VPS 部署 → 本机状态」里可修改密码（需当前密码，改后其他设备自动退出） |
| 添加到手机桌面 | 「设置 → VPS 部署 → 本机状态」里扫码，在手机上把 DSH 当作应用添加到主屏幕，全屏打开、像原生应用一样使用 |
| 浏览器初始向导 | 管理员账号、域名、DeepSeek API Key、预置插件，全程在浏览器里填完 |
| 中英双语 | 登录页、初始向导、启动等待页按浏览器语言显示中文或英文，右上角可手动切换并记住；DSH 内的「VPS 部署」页与升级提示条跟随 DSH 的语言设置 |
| 一次性启动令牌 | 向导只对持有令牌的人开放，链接随安装输出，`dsh-vps setup-url` 可重取，设置完成即作废 |
| 预置插件一键装 | 向导内置 3 款：本产品的设置页 dsh-vps（必装），以及插件市场与 VPS 管理（默认勾选、可取消）；后台装完自动重启生效 |
| 自动 HTTPS | Caddy 自动签发并续期证书；向导里改域名即时热加载 |
| 公网可用的原生设置页 | 设置、模型、API Key、权限策略在公网域名下照常读写 |
| 插件市场可用 | 市场里浏览/安装插件，点「立即重启」直接生效 |
| 会话自愈 | DSH 首启与插件安装需要几十秒，页面自动等待，就绪后自动进入 |
| 跟随官方一键升级 | DSH 出新版本时页面提示，在「设置 → VPS 部署」里点一下升级；升级走备份 → 自检 → 失败自动回滚，也可随时手动回滚 |
| 可观测与可恢复 | 本机 `/gate/health` 直接给出崩溃原因与连续崩溃次数；`dsh-vps backup` 保留最近 3 份 |
| 收紧的暴露面 | 会话 Cookie 恒为 Secure/HttpOnly/SameSite；诊断接口只对服务器本机与已登录会话开放；服务以无特权的 dsh 用户运行并受 systemd 沙箱约束 |

---

## 截图

<p align="center">
  <img src="docs/demo.gif" alt="全流程演示：安装 → 设置向导 → 登录 → DSH 界面 → 插件市场" width="1000">
</p>

<details>
<summary><strong>展开查看 12 张原图</strong>（DSH 里的「VPS 部署」页 → 安装 → 向导 → 设置完成 → 登录 → DSH 界面 → 设置 → 插件市场）</summary>

<br>

| 在 DSH 里填表安装到 VPS | 从 VPS 卸载 | VPS 上的「本机状态」 |
| :---: | :---: | :---: |
| ![](docs/screenshots/00a-deploy-install.webp) | ![](docs/screenshots/00b-deploy-uninstall.webp) | ![](docs/screenshots/00c-deploy-status.webp) |

| 安装完成 | 初始设置向导 | 向导已填写 |
| :---: | :---: | :---: |
| ![](docs/screenshots/01-install.png) | ![](docs/screenshots/02-setup.png) | ![](docs/screenshots/03-setup-filled.png) |

| 设置完成 | 登录门 | 登录 |
| :---: | :---: | :---: |
| ![](docs/screenshots/04-setup-done.png) | ![](docs/screenshots/05-login.png) | ![](docs/screenshots/06-login-filled.png) |

| DSH 原生界面 | 设置（公网域名下可用） | 插件市场 |
| :---: | :---: | :---: |
| ![](docs/screenshots/07-dsh.png) | ![](docs/screenshots/08-settings.png) | ![](docs/screenshots/09-market.png) |

</details>

---

## 环境要求

- Ubuntu 22.04+ / Debian 12+（root）
- 2C2G 以上，端口 80/443 开放
- 有域名即可自动 HTTPS（先把 A 记录解析到本机）；暂无域名也能先用公网 IP + 自签证书

---

## 安装

### 方式一：在自己电脑上的 DSH 里填表安装

Mac、Windows、Linux 上的 DSH 都可以：

1. 在 DSH 里装上插件 `dsh-vps`：插件市场搜索安装，或执行 `dsh plugin add dsh-vps`
2. 打开「设置 → VPS 部署」，填服务器 IP、SSH 端口、用户名，选登录方式；有域名（A 记录已解析到服务器）再填上域名，服务器在国内就勾上「服务器在国内」
3. 点「安装到这台 VPS」

- 登录方式三选一：**密码**；**私钥**（粘贴或选择云厂商给的 .pem / 自己的 id_ed25519，可带口令）；**本机密钥**（一键生成专用密钥，复制公钥或那行命令到云厂商控制台的网页终端执行一次，~/.ssh 里已有的密钥也会一并尝试）。服务器关掉了密码登录（重装系统后常见）时用后两种
- 密码、私钥只用这一次，不保存；本机密钥的私钥只留在这台电脑上
- 页面实时显示安装日志，完成后直接给出设置向导的链接
- 安装在服务器上后台运行，中途关掉页面或网络断开都不影响
- 需要本机有 OpenSSH 客户端：Mac、Linux 自带；Windows 10/11 在「设置 → 系统 → 可选功能」里添加「OpenSSH 客户端」

### 方式二：在 VPS 上执行一键安装命令

```bash
curl -fsSL https://raw.githubusercontent.com/AIcivilization/dsh-vps/main/install.sh \
  | sudo bash -s -- --domain dsh.example.com
```

国内网络加 `--mirror cn`（Node 与 DSH 走 npmmirror）：

```bash
curl -fsSL https://raw.githubusercontent.com/AIcivilization/dsh-vps/main/install.sh \
  | sudo bash -s -- --domain dsh.example.com --mirror cn
```

还没有域名？去掉 `--domain` 即可，按公网 IP 访问：

```bash
curl -fsSL https://raw.githubusercontent.com/AIcivilization/dsh-vps/main/install.sh | sudo bash -s
```

此时证书由 Caddy 内置 CA 自签，浏览器会提示「不安全 / 证书不受信任」，属预期现象，选择继续访问即可。之后在向导里填上域名，Caddy 自动换成正式证书。（方式一不填域名时也是这样。）

走 npm 也行，装的是这个包自带的同一份脚本（版本固定，不联网拉取；需本机已有 Node 22+）：

```bash
npx dsh-vps-install install --domain dsh.example.com
```

想固定在某个发布版本（而非 `main`），把地址里的 `main` 换成版本 tag，并让后续拉取的网关文件也用同一版本：

```bash
curl -fsSL https://raw.githubusercontent.com/AIcivilization/dsh-vps/v1.7.0/install.sh \
  | sudo DSHVPS_RAW_BASE=https://raw.githubusercontent.com/AIcivilization/dsh-vps/v1.7.0 bash -s -- --domain dsh.example.com
```

安装末尾的自检若报「DSH 尚未就绪」，设置链接照样会打印；页面会显示启动进度与具体错误，排障见 `journalctl -u dsh-gate -n 80 --no-pager`。

## 更新

**新装直接是官方最新版。** 安装时取 npm 上官方最新版（与下面的升级提示同一规则：latest 与 next 中较新、发布满 12 小时）；万一装不上或装好起不来，自动退回本项目验证过的版本。想指定版本：安装命令末尾加 `--dsh <版本>`，或 `--dsh verified` 装验证过的版本。

**DSH 本身跟随官方版本升级。** 网关每 6 小时检查一次 npm 上的官方最新版（正式渠道 latest 与预览渠道 next 中较新的一个），有新版本时 DSH 页面右下角弹出提示（也可以在「设置 → VPS 部署」里查看和操作），点「立即升级」并确认即可：自动备份 → 安装新版 → 自检，自检不通过自动回滚到原版本，全程约 1–3 分钟。点「稍后」则这个版本不再提示。新版本发布满 12 小时后才会提示——上游常有“主包先发、子包几小时后才补齐”的情况，刚发布就升级只会装失败。也可以在服务器上手动执行：

```bash
sudo dsh-vps upgrade            # 升到本项目验证过的版本
sudo dsh-vps upgrade --latest   # 升到官方最新版（与页面上的「立即升级」相同）
sudo dsh-vps rollback           # 切回上一个版本
```

**网关（登录页、代理）自身的更新**：

```bash
sudo dsh-vps update-gate
```

v1.5.0 之前安装的机器，重跑一次上方的一键安装命令即可获得页面升级提示（进入修复/更新模式，账号与数据保留）。

## 卸载

```bash
curl -fsSL https://raw.githubusercontent.com/AIcivilization/dsh-vps/main/uninstall.sh \
  | sudo bash -s -- --yes
```

**在自己电脑上的 DSH 里卸载**：「设置 → VPS 部署」→「从 VPS 卸载」，填服务器登录信息，选择是否保留 DSH 数据、是否连 Caddy 一起移除，点「从这台 VPS 卸载」。默认保留 DSH 数据。

也可以在服务器上执行上面的命令：删除服务、安装目录、Caddy 站点块与 DSH 数据目录，删除前打包备份（含 Caddyfile）到 `/root/dsh-vps-uninstall-<时间戳>.tar.gz`。安装前原有的 Caddyfile 会被还原。`--keep-data` 保留 DSH 数据，`--purge-caddy` 连 Caddy 一起移除。卸载完再跑安装命令即为全新环境。

---

## 首次使用

安装结束时会给出一条**带一次性令牌的初始设置链接**（命令行安装打印在终端里，填表安装显示在设置页上），浏览器打开它进入向导（直接打开 IP 或域名只会看到「需要启动令牌」页，这是有意的）：填管理员用户名/密码 → （可选）域名、DeepSeek API Key 与预置插件 → 登录即用。向导只对持有令牌的人开放，令牌在设置完成后自动作废。链接丢了随时重取：

```bash
sudo dsh-vps setup-url
```

API Key 跳过也无妨，登录后仍可在「添加 API Key」引导或 设置 → 模型 → DeepSeek 中补填。

插件在后台安装（约几十秒），始终取 npm 上的最新版本，装完 DSH 自动重启生效，共三款：

- **dsh-vps**（本产品自带，必装）：DSH 设置里的「VPS 部署」页，分三个页签——「本机状态」（DSH 版本与一键升级、网关状态与访问方式、服务器常用命令）、「安装到 VPS」「从 VPS 卸载」（经 SSH 把 DSH 装到或卸出另一台 VPS）。装在自己电脑上的 DSH 里时只有后两个页签。界面语言跟随 DSH「设置 → 通用设置 → 语言」，目前 DSH 提供中文与英文，切换后立即生效；页面上的升级提示条同样跟随

- **dsh-market**：设置页内浏览、搜索、一键安装社区插件与主题。其余插件留给你自己挑，装好后在市场里按需添加
- **dsh-vps-manager**：在 DSH 里直接管理这台 VPS——`/vps-` 系列查询命令不经过模型、不花 token，对话内嵌终端，AI 操作按风险分级确认，另有运维菜谱库。需在 设置 → VPS Manager 中添加本机（SSH 密钥登录）

---

## 管理命令

```bash
sudo dsh-vps status        # 服务状态 + 健康 + 版本提示
sudo dsh-vps restart       # 重启（DSH 随之重启并自动重新兑换会话）
sudo dsh-vps upgrade       # 升级 DSH 到已验证版本（备份 → 自检 → 失败自动回滚）
sudo dsh-vps update-gate   # 拉取并重启网关自身代码（安装目录非 git 仓库，无需 git pull）
sudo dsh-vps ownshost on   # 应用设置页可用性补丁（公网域名下恢复设置页）
sudo dsh-vps selfcheck     # 跑一遍回归自检（登录 / RPC / WebSocket / 会话）
sudo dsh-vps rollback      # 切回上一 DSH 版本
sudo dsh-vps reset-admin   # 忘记管理员密码时的应急重置（重新走向导并换发令牌，已登录的会话全部失效）
sudo dsh-vps setup-url     # 重新打印带一次性令牌的初始设置链接
sudo dsh-vps backup        # 备份数据（保留最近 3 份）
```

Caddy 站点块由 `gate/site-block.js` 统一生成，安装与改域名共用同一份模板。

---

## 运行机制

<p align="center">
  <img src="assets/architecture.svg" alt="请求链路：浏览器 → Caddy → dsh-gate → dsh web" width="680">
</p>

DSH 与网关均只绑 127.0.0.1，用户浏览器接触不到 DSH 的会话 Cookie，所有请求经网关认证后透传。

- **会话自愈**：首启与插件安装期间页面显示「DeepSeek Harness 正在启动」，按 3 秒一次自检，会话就绪后自动刷新进入。
- **设置页可用性**：DSH 前端按页面 hostname 判断是否为操作者本机浏览器，公网域名下会隐藏设置。网关随页面下发官方支持的 `__DSH_TRANSPORT__.ownsHost` 声明，设置页、模型、API Key 与权限策略随之恢复。`--trusted-host` 只负责打开网络围栏，两者是两道独立的门。
- **插件市场重启**：市场的「立即重启」由网关接管——它剥掉 Caddy 加的 `X-Forwarded-For`（该头会触发 DSH 的回环校验而 403），并由网关重启自己托管的 DSH 子进程，保证会话兑换链路不中断。
- **排障入口**：`sudo ss -ltnp | grep 3080` 查残留 DSH 进程；服务器上执行 `curl -s http://127.0.0.1:3100/gate/health` 可拿到 `lastError` / `lastExit` / `crashStreak`（该接口只对服务器本机与已登录会话开放）

---

## 仓库内容

| 文件 | 作用 |
| --- | --- |
| `install.sh` | 一键安装入口（唯一可选参数 `--domain`、`--mirror cn`） |
| `uninstall.sh` | 卸载并备份 |
| `bin/dsh-vps` | 运维命令行 |
| `gate/server.js` | 登录网关（Node 原生，零依赖） |
| `gate/site-block.js` | Caddy 站点块模板（安装 / 改域名共用） |
| `caddy/Caddyfile.template` | Caddy 主配置 |
| `units/dsh-gate.service` | systemd 单元模板 |
| `versions.json` | DSH 已验证版本清单 |
| `plugin/` + `cordis.patch.yml` | DSH 插件：「设置 → VPS 部署」（版本与一键升级、网关状态；或填表经 SSH 安装到 VPS） |

---

## 许可

[MIT](LICENSE)
