Skip to content
cleeate 的博客
Go back

在 Debian 12 小 VPS 上从零部署 DSH 并接通 Telegram 机器人

Updated:

本文记录一次真实部署的完整过程和踩坑经验。环境:Debian 12、2 核 CPU、约 925MB 内存、39GB 磁盘。 文中所有密钥、Token、密码、用户 ID、机器人用户名一律用占位符表示,公开发布前请务必替换,并不要把真实 Token 写进文章或代码仓库。

避坑总览:先看这五条

  1. 小内存先加 Swap,再装 DSH。 不加 Swap,npm 安装 DSH 时很容易被 OOM killer 杀掉,表现为安装莫名中断、dsh 命令缺失、服务起不来。
  2. 不要装旧的 dsh-telegram。 新版教程用的是 @xmanrui/dsh-im,两者不要混装。
  3. Token 只走 DSH 设置界面。 不要把 Bot Token 写进 cordis.patch.yml、settings.yaml 或任何会被提交的文件。
  4. 私聊一定要开白名单。 dsh-im 默认对所有私聊开放,不设白名单等于谁都能指挥你的机器人。
  5. 模型选错是最高频的报错来源。 要 Key 的官方模型、要 GitHub 授权的 EAC 模型、免密的 Kilo 免费池,这三类不要混着选。

一、服务器准备

1. 改主机名(可选,但建议做)

hostnamectl set-hostname b2

并在 /etc/hosts 里加一行:

127.0.1.1 b2

2. 检查资源

free -m        # 查看内存与已有 Swap
df -h          # 确认根分区剩余空间大于 2GB

如果 free -m 里 Swap 全为 0,说明机器没有预置交换,继续下一步。

3. 创建 2GB Swap

fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile

老版本若不支持 fallocate,可用 dd if=/dev/zero of=/swapfile bs=1M count=2048 代替。

开机自动挂载并调低 swappiness:

echo '/swapfile none swap sw 0 0' >> /etc/fstab
sysctl vm.swappiness=10
echo 'vm.swappiness=10' >> /etc/sysctl.conf

swappiness 默认是 60,小内存机器会把数据过早换出、拖慢性能;设为 10 表示只在内存紧张时才动用 Swap。再执行 free -m,Swap 应显示约 2048MB。

补充说明:如果云厂商给你的是静态公网 IP,但网卡上只显示内网地址,这多半是 NAT 映射,属正常现象,只要出站 IP 和入站 SSH 到的都是同一台机器即可。

4. 装基础工具

apt update
apt install -y curl ca-certificates gnupg git

二、安装 Node 和 DSH

用 NodeSource 装 Node 22:

curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt install -y nodejs
node -v
npm -v

实测版本:Node v22.23.4、npm 10.9.9。

全局安装 DSH,并补装 pnpm(插件安装需要它,缺了会报 pnpm 未找到):

npm install -g @deepseek-ai/dsh
npm install -g pnpm
dsh --version

实测 DSH 版本:0.2.1-rc.5。

长耗时安装建议脱离 SSH 会话运行,例如用 setsid / nohup 后台跑,避免 SSH 断线把安装进程一起带走。SSH 偶尔出现 banner 交换超时,多半是网络抖动,先重试,不要轻易判定服务器挂了。

三、安装免费模型插件和 IM 插件

1. 免费模型插件

dsh plugin --profile web add github:Ebony-Vinyl/dsh-our-free-model

实测版本:2.8.0。

注意两点:

  • 不要同时把它写进 cordis.patch.yml,重复注册会出问题。
  • 用下面的命令检查,our-free-model 应该只出现一次:
dsh --profile web --dump-config

2. IM 插件(Telegram 对接)

dsh plugin --profile web add -w @xmanrui/dsh-im

实测版本:5.9.1。

最终 bundles 顺序应为:

@deepseek-ai/dsh-base
@deepseek-ai/dsh-web-app
dsh-our-free-model
@xmanrui/dsh-im

再次检查 dump-config,确认 our-free-model 和 @xmanrui/dsh-im 都在,且没有旧的 dsh-telegram。

四、用 systemd 跑 DSH,不要对外暴露 Web UI

教程本身只要求前台跑 dsh --profile web,但为了让机器人 survives 重启,建议写一个 systemd 服务。关键点:Web UI 只监听本地,Telegram 走长轮询,不需要开放任何入站端口。

/etc/systemd/system/dsh.service 示例:

[Unit]
Description=DSH Telegram Agent
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=root
WorkingDirectory=/root
Environment=DSH_HOME=/root/.dsh
Environment=HOME=/root
ExecStart=/usr/bin/dsh --profile web
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

启动并验证:

systemctl daemon-reload
systemctl enable dsh
systemctl start dsh
systemctl status dsh --no-pager
ss -tlnp | grep -E '3080|8326'

正常情况下服务是 active,且 3080、8326 只出现在 127.0.0.1 上,不要在防火墙或安全组里放行它们。

五、绑定 Telegram 机器人

  1. 在 BotFather 创建机器人,拿到 Bot Token,记好但不要发到公开场合。
  2. 打开 DSH 的「设置 → IM机器人」,选择 Telegram,粘贴 Token 并保存。
  3. 务必开启私聊白名单模式,填入自己的数字 USER_ID,例如:
<你的数字 USER_ID>

只放你一个人。群聊默认是开放模式,如需收紧要另外设置,不要以为开了私聊白名单群聊就自动安全了。

绑定成功后,机器人应显示已连接、长轮询正常。绑定信息保存在 ~/.dsh/integrations/dsh-telegram/,Token 在里面是引用形式,不是明文,但这不等于可以把该目录公开分享。

六、模型选择避坑:这是本次部署最关键的一节

dsh-im 的模型列表里混了三类模型,选错就会报错:

类型表现能不能在服务器上用
DeepSeek 官方模型,如 deepseek-flash没有 Key 时报缺少凭据没配 Key 就不能用
EAC 模型,如 opencode/deepseek-v4.1-flash-free报 401,需要 GitHub 授权并 star 仓库服务器上用不了,它是桌面端取向的渠道
Kilo 免费池,如 kilo-auto/free免账号、免 Key可以,这就是默认该选的

正确做法:把默认模型写进 ~/.dsh/profiles/web/cordis.patch.yml 的 agent-default-model:

- id: agent-default-model
  name: "@deepseek-ai/dsh-agent-default-model"
  config:
    provider: our-free-model
    model: kilo-auto/free
    reasoningEffort: high

改完重启服务:

systemctl restart dsh
systemctl is-active dsh
dsh --profile web --dump-config | grep -A4 agent-default-model

重要:改完模型一定要在 Telegram 里先发 /new 开新会话,再发正常消息。 旧会话还钉在旧模型上,不换会话,报错会继续出现。这一步最容易被忽略。

七、验证清单

按顺序全部通过,才算部署完成:

  • systemctl status dsh 是 active
  • 3080、8326 只监听在 127.0.0.1
  • Telegram 发 /start 有回复
  • Telegram 发 /status 能看到会话和模型
  • Telegram 发 /new 后,再发一句正常消息能正常回复
  • 没有出现“任务结果未确认”“内部未知错误”之类的提交失败提示

八、常见问题

Q:npm 安装 DSH 装到一半就没了,dsh 命令也不存在? A:先看内存和 Swap,十有八九是 OOM killer 杀了 npm。按第一节补 2GB Swap 再重装,不要反复在没 Swap 的机器上硬装。

Q:插件安装报 pnpm 未找到? A:先全局装 pnpm 再装插件。

Q:/start 失败,提示缺少凭据? A:会话默认模型走了 DeepSeek 官方渠道,但你没配 Key。按第六节把默认模型改成 Kilo 免费池,再 /new。

Q:正常消息报 401,要 GitHub 授权 star 仓库? A:你选到了 EAC 模型。换回 kilo-auto/free,再 /new。不要尝试绕过 EAC 的授权闸门。

Q:改了模型还是报错? A:先确认你是不是还在旧会话里。/new 之后再测一次;同时用 journalctl -u dsh --no-pager | tail -n 100 看服务日志,用 Telegram 的 /status 看当前会话到底用的是哪个模型。

Q:SSH 经常断,b2 是不是挂了? A:不一定。先重试连接,再看服务状态。长安装一定要脱离 SSH 会话跑,断线才不会中断安装。

九、发布前的安全提醒

  • 不要把 Bot Token、服务器密码、API Key 写进教程、截图或代码仓库。
  • 数字 USER_ID、白名单、机器人用户名在公开发布时建议用占位符或打码。
  • Web UI 只监听本地是刻意为之,不要为了图方便把它暴露到公网。


Next Post
让 Hermes 替你