Featured image of post VPS-telegram 配置笔记

VPS-telegram 配置笔记

记录 Telegram 机器人在 VPS 上的开发、部署、GitHub Actions 自动更新与 systemd 托管的完整流程。

一、整体流程和核心思路

这套方案的目标是:

  1. 在本地编写和修改 Telegram 机器人代码
  2. 将代码 push 到 GitHub
  3. 由 GitHub Actions 自动触发部署
  4. GitHub 通过 SSH 登录 VPS
  5. VPS 上自动拉取最新代码、更新依赖、重启机器人服务
  6. 最终可以在 Telegram 中通过命令查看 VPS 状态

这套流程的核心思路不是“让 GitHub 直接替代 VPS 运行程序”,而是把职责拆开:

  • 本地:负责开发和提交代码
  • GitHub:负责触发自动部署
  • VPS:负责真正运行机器人
  • systemd:负责守护机器人进程,确保自动重启和开机自启

为了让权限更清晰,这次最终采用的是:

  • root:只负责让 GitHub Action 通过 SSH 登录 VPS
  • debian:负责项目目录、git pull、Python 虚拟环境、bot 运行

这样做的原因是:

  • 应用不直接用 root 跑,更安全
  • 项目文件归属统一,不容易出现 Git 的 ownership 报错
  • 部署链路和运行链路职责清晰,后续更容易维护

二、最终部署架构

最终的运行结构如下:

  1. 本地修改代码后执行 git push origin main
  2. GitHub Actions 触发 .github/workflows/deploy-to-vps.yml
  3. Action 使用 root 的 SSH 密钥连接 VPS
  4. 登录后切换到 debian 用户执行部署脚本
  5. debian/home/debian/apps/VPS-telegram 中执行:
    • git fetch
    • git reset --hard origin/main
    • 安装 Python 依赖
    • 重启 vps-telegram-bot.service
  6. systemd 使用虚拟环境中的 Python 启动 main.py
  7. Telegram 机器人继续运行最新代码

三、本地代码改造思路

1. 凭据不能写死在代码里

最开始 main.py 中直接写了:

  • API_TOKEN
  • ADMIN_ID

这样虽然能跑,但不适合部署,因为:

  • token 泄露风险高
  • 更换 token 需要修改代码
  • 不适合区分本地环境和 VPS 环境

因此改成了从 .env 读取:

1
2
API_TOKEN = os.getenv("API_TOKEN")
ADMIN_ID = os.getenv("ADMIN_ID")

并在代码中加入缺失检查,避免服务看似启动但实际没配置成功。

2. 增加依赖和忽略规则

为了让 VPS 能自动安装环境,仓库中补充了:

  • requirements.txt
  • .env.example
  • .gitignore

其中:

  • .env 不提交到 GitHub
  • .env.example 只保留变量模板
  • .venv、缓存文件、流量统计文件也不提交

3. /status 输出内容扩展

状态信息最终包含:

  • 服务器状态
  • CPU
  • 内存
  • Ping值
  • 下载速度
  • 今日流量
  • 近三十日流量

同时输出文案统一改为了中文,方便直接在 Telegram 中查看。

4. 下载速度测量逻辑优化

最开始下载速度依赖后台流量线程定期更新,容易显示为 0,因为:

  • 用户发 /status 时不一定正好处于采样更新窗口
  • 60 秒周期过长,不适合展示瞬时速度

后来改成在执行 /status 时做一次短时实时采样:

  • 在很短时间内读取两次 psutil.net_io_counters().bytes_recv
  • 根据时间差和接收字节差计算下载速度

这样更适合展示“当前时刻的大致下载速度”。


四、GitHub 端配置思路

1. GitHub Actions 的作用

GitHub Actions 的职责是:

  • 在代码 push 到主分支时自动触发
  • 通过 SSH 登录 VPS
  • 在 VPS 上执行部署脚本

2. 使用的关键 Secrets

仓库中配置了这些 GitHub Secrets:

  • VPS_HOST
  • VPS_USER
  • VPS_SSH_KEY
  • VPS_PORT
  • VPS_REPO_DIR

其中:

  • VPS_USER 最终使用的是 root
  • VPS_REPO_DIR/home/debian/apps/VPS-telegram

3. 为什么不是直接用 debian SSH 登录

实际环境中只有 root 有 SSH 登录能力,因此最终采用:

  • root 负责 SSH 登录 VPS
  • 登录后通过 sudo -u debian -H bash -lc 切换到 debian
  • debian 执行真正的更新操作

这是这次部署成功的关键调整之一。


五、VPS 端配置思路

1. 为什么需要普通用户 debian

虽然一开始很多操作都是用 root 完成的,但应用最终不应该一直用 root 运行。

使用 debian 的好处:

  • 权限更小,更安全
  • 项目目录归属清晰
  • 便于管理 .env.venv、git 仓库
  • 避免 Git 出现 dubious ownership 问题

2. 项目目录

项目最终放在:

1
/home/debian/apps/VPS-telegram

这个目录及其内容最终应归:

1
debian:debian

3. VPS 访问 GitHub 的 deploy key

GitHub Action 能登录 VPS,不代表 VPS 自己能从 GitHub 拉代码。

因此还需要给 debian 单独配置一把 SSH key,用于:

1
2
git fetch
git pull

这把 key 的公钥加到 GitHub 仓库的:

Settings -> Deploy keys

它的作用是:

  • 允许 VPS 上的 debian 用户访问 GitHub 仓库
  • 不负责登录 VPS

4. .env 文件在哪里写

真实凭据不应该提交到 GitHub,因此 .env 应直接写在 VPS 项目目录中:

1
/home/debian/apps/VPS-telegram/.env

例如:

1
2
3
API_TOKEN=your_bot_token
ADMIN_ID=your_telegram_id
PING_TARGET=www.sjtu.edu.cn

5. Python 虚拟环境

在 VPS 上使用:

1
python3 -m venv .venv

然后安装依赖:

1
.venv/bin/pip install -r requirements.txt

这样 bot 的依赖和系统 Python 隔离,后续维护更稳定。


六、systemd 服务配置思路

1. 为什么要用 systemd

因为 bot 需要长期运行,仅靠前台执行 python main.py 不够稳定。

使用 systemd 的好处:

  • 开机自启
  • 进程异常退出后自动重启
  • 日志可以用 journalctl 查看
  • 便于 GitHub Action 自动重启服务

2. 服务实际配置

最终服务大致为:

1
2
3
4
5
6
[Service]
User=debian
WorkingDirectory=/home/debian/apps/VPS-telegram
EnvironmentFile=/home/debian/apps/VPS-telegram/.env
ExecStart=/home/debian/apps/VPS-telegram/.venv/bin/python /home/debian/apps/VPS-telegram/main.py
Restart=always

这表示:

  • bot 由 debian 用户运行
  • 从项目目录读取 .env
  • 使用虚拟环境中的 Python 启动

七、自动部署脚本思路

1. GitHub Actions 工作流

工作流负责:

  1. checkout 仓库
  2. 通过 SSH 登录 VPS
  3. 进入项目目录
  4. 调用部署脚本

2. VPS 更新脚本

更新脚本负责:

  1. git fetch origin main
  2. git checkout main
  3. git reset --hard origin/main
  4. 安装或更新依赖
  5. systemctl restart vps-telegram-bot.service

这样每次 push 后,VPS 都会自动同步到远端最新版本。


八、这次实际遇到的问题与解决方式

1. GitHub Action 缺少 VPS_HOST

现象:

  • Action 报错 missing server host

原因:

  • GitHub Secrets 中缺少 VPS_HOST

解决:

  • 在仓库 Secrets 中补充 VPS_HOST

2. GitHub Action 缺少 VPS_REPO_DIR

现象:

  • 报错 VPS_REPO_DIR secret is not set

解决:

  • 在仓库 Secrets 中增加 VPS_REPO_DIR=/home/debian/apps/VPS-telegram

3. Git 报 dubious ownership

现象:

  • 部署时 Git 认为仓库目录所有权可疑

原因:

  • SSH 登录用户和项目目录拥有者不一致

解决:

  • 保持项目目录归 debian
  • GitHub Action 登录后切换到 debian 执行部署

4. debian 无法从 GitHub 拉代码

现象:

  • git@github.com: Permission denied (publickey)

原因:

  • debian 用户没有配置访问 GitHub 的 deploy key

解决:

  • debian 单独生成 GitHub key
  • 将公钥加入仓库 Deploy keys

5. sudo systemctl restart 要密码

现象:

  • debian 执行重启服务时要求输入密码

原因:

  • 无人值守部署时,debian 没有免密码执行 systemctl 的权限

解决:

  • visudo 中添加 sudoers 规则

例如:

1
debian ALL=(ALL) NOPASSWD: /bin/systemctl

6. GitHub Action 成功但 Telegram 没显示新字段

现象:

  • Action 成功,但 /status 仍显示旧内容

原因:

  • git fetch 了代码,没有真正切换到新版本或服务未重启

解决:

  • 确认执行 git reset --hard origin/main
  • 然后重启 vps-telegram-bot.service

7. 下载速度一直为 0

原因:

  • 旧逻辑依赖后台周期更新,不适合瞬时显示

解决:

  • 改成 /status 时实时短时采样下载速度

九、最终日常使用方式

以后日常更新流程如下:

本地更新代码

1
2
3
git add .
git commit -m "your update"
git push origin main

GitHub 自动部署

push 后会自动:

  1. 触发 GitHub Action
  2. SSH 登录 VPS
  3. 切换到 debian
  4. 拉取最新代码
  5. 更新依赖
  6. 重启 bot 服务

Telegram 中使用

在 Telegram 中向 bot 发送:

1
/status

即可查看当前 VPS 状态。


十、常用排查命令

查看服务状态

1
systemctl status vps-telegram-bot.service --no-pager

查看最近日志

1
journalctl -u vps-telegram-bot.service -n 100 --no-pager

实时查看日志

1
journalctl -u vps-telegram-bot.service -f

查看当前代码是否已更新

1
2
cd /home/debian/apps/VPS-telegram
git log -1 --oneline

手动同步到最新代码

1
sudo -u debian -H bash -lc 'cd /home/debian/apps/VPS-telegram && git fetch origin main && git reset --hard origin/main'

手动重启 bot 服务

1
sudo systemctl restart vps-telegram-bot.service

十一、这套方案的最终优点

这次搭好的方案有这些明显优点:

  1. 代码修改后只需要 push,不需要手动登录 VPS 逐次更新
  2. 凭据从代码中分离,安全性更高
  3. 项目由普通用户 debian 运行,更安全
  4. 使用 systemd,稳定性高,支持自动重启
  5. 日志和服务状态清晰,便于维护
  6. Telegram 中可以方便地直接查看 VPS 运行状态

十二、后续可继续优化的方向

后续如果继续增强,可以考虑加入:

  1. 磁盘占用
  2. 系统负载
  3. 在线时长
  4. 定时日报
  5. 网络入站速度和出站速度同时展示
  6. 多个 ping 目标对比
  7. 命令白名单和更丰富的权限控制

这份笔记的目的,是把这次从零到跑通的实际过程完整记录下来,后续无论迁移服务器、重新部署,还是继续扩展功能,都可以直接以此为基准继续维护。