聊天机器人搭建05
【从零搭建聊天机器人】05 自动化运维:使用 GitHub Actions 实现 CI/CD 云端自动部署
写在前面
欢迎来到《从零搭建聊天机器人》系列教学的第五章,也是我们系统架构中最具“现代化工程师”色彩的一课!
在传统的日常更新中,你不仅要在本地改,还要连上云服务器,手动执行git pull、停止老进程、再重新启动新进程……这一套操作既繁琐又容易出错。
本章我们将引入现代软件开发的核心利器——CI/CD(持续集成与持续部署)。我们将利用GitHub Actions打造一条自动化流水线:只要你在本地电脑一敲git push,云端的 AWS 服务器就会自动完成代码拉取、环境更新并重启后台服务。真正实现“代码一推,服务起飞”!
文章目录
- 🎯 学习目标 (Intended Learning Outcomes)
- 01 解决痛点:让机器人在云端“后台长驻”
- `nohup` 命令说明
- 02 配置 GitHub Secrets:授予自动化部署权限
- 操作步骤
- 03 编写 GitHub Actions 工作流 (YAML 脚本)
- 1. 创建工作流文件
- 2. 编写自动化剧本
- 触发条件:当有新的 commit 被 push 到 main 分支时自动触发
- 04 触发自动部署与流水线测试
- 05 踩坑实录:自动化部署中的那些致命报错
- ❌ 错误一:Telegram API 报错 `Conflict: terminated by other getUpdates request`
- ❌ 错误二:Actions 日志提示 `git pull: Please commit your changes or stash them`
- ❌ 错误三:YAML 解析错误
- ❌ 错误四:SSH Key 解析错误
- 💡 06. 深度思考题与参考答案 (Reflection & Solutions)
- 📝 文章摘要
🎯 学习目标 (Intended Learning Outcomes)
学完本章节实验,你将能够掌握以下核心技能:
- 进程管理掌握在 Linux 中使用
nohup使程序在后台持久运行的方法,解决“断开连接即死机”的问题。 - 安全凭证管理掌握 GitHub Secrets 的配置,实现第三方服务安全免密访问 AWS 资源。
- 流水线搭建编写 YAML 工作流文件,配置 GitHub Actions 自动化部署管道(Automate deployment using GitHub Actions)。
- 异常处理掌握解决自动化部署中常见的进程冲突(如 Telegram API 抢占)与 Git 合并冲突问题。
01 解决痛点:让机器人在云端“后台长驻”
GitHub Actions 和 CI/CD 简介
GitHub Actions 是一个 CI/CD 平台,可以自动化构建、测试和部署流水线。
- 持续集成 (CI):每次提交都会触发自动化构建/测试,以确保顺利集成。
- 持续交付 (CD):一旦验证通过,代码会自动部署到目标环境(这里是 AWS EC2)。
工作流程组件
- 工作流程:自动化程序,存储于 .github/workflows 中。
- 事件:触发条件(例如,提交或推送操作)。
- 任务:收集在跑轮上执行的各个步骤。
- 步骤:单个任务(操作或命令)。
- 动作:可重复使用的命令块。
- 运行器:负责执行任务的服务器。
为什么终端关闭机器人就停止回复了:
当你通过 SSH 连接到 EC2 时,实际上是开启了一个会话(Session)。你在终端里运行的python chatbot.py依附于这个会话。当你直接关闭终端时,Linux 会向该会话下的所有程序发送一个名叫SIGHUP(挂断)的死亡信号,机器人自然就跟着殉情了。
要让机器人 24 小时独立运行,我们需要把它挂载到系统后台。
nohup命令说明
nohuppython chatbot.py>chatbot.log2>&1&nohup:No Hang Up 的缩写,意思是“忽略挂断信号”,告诉系统即使关闭终端也不要杀掉这个程序。> chatbot.log:因为程序跑在后台,你在屏幕上将看不到任何日志了。这个指令把原本输出在屏幕上的日志,全部重定向保存到一个叫chatbot.log的文件中。2>&1:将“错误信息”也一并塞进这个日志文件里。&:关键标志,代表将其放入系统后台运行。
敲下回车后,终端会返回一串数字(比如[1] 12345),这是程序的进程 ID (PID)。现在,你可以放心地直接关掉 SSH 终端窗口了,拿出手机测试,你会发现机器人依然坚挺在线!
02 配置 GitHub Secrets:授予自动化部署权限
现在我们要让 GitHub 帮我们自动登录 EC2 服务器并执行更新命令。这就要求 GitHub 必须知道你的服务器 IP、用户名以及那把极其私密的.pem钥匙。为了安全,我们绝对不能把这些写在代码里,而是要存在 GitHub 的“保险箱”——Secrets中。
操作步骤
- 打开你的 GitHub 网页,进入
Chatbot项目仓库。 - 点击上方的Settings(设置)选项卡。
- 在左侧边栏找到Secrets and variables➔ 选择Actions。
- 点击绿色的New repository secret按钮,我们需要依次创建三个机密变量:
变量 1:EC2_HOST
Name:
EC2_HOSTSecret:填入你的 EC2 公网 DNS 地址(例如:
ec2-18-167-37-17.ap-east-1.compute.amazonaws.com)变量 2:EC2_USER
Name:
EC2_USERSecret:填入
ec2-user变量 3:EC2_SSH_KEY
Name:
EC2_SSH_KEYSecret:用本地电脑的记事本或 VS Code 打开你的
.pem密钥文件,将里面所有的内容(包括-----BEGIN...和...END KEY-----以及所有的换行)一字不落地全部复制进去。
03 编写 GitHub Actions 工作流 (YAML 脚本)
请打开EC2,确保EC2的状态为running
准备工作就绪,我们要开始写指挥 GitHub Actions 干活的剧本了。
1. 创建工作流文件
回到你的本地电脑(Windows),在Chatbot项目的根目录下,新建一个文件夹树:
用Git Bash执行代码
mkdir-p.github/workflows或
手动创建创建一个名为.github的文件夹 ➔ 在它里面创建一个叫workflows的文件夹
然后在里面新建一个文件叫deploy.yml。
最终的路径结构必须严格是:.github/workflows/deploy.yml
2. 编写自动化剧本
用你的代码编辑器打开deploy.yml,将以下内容完整复制进去。请注意,YAML 文件对空格极其敏感,请绝对不要乱按 Tab 键或删改缩进!
触发条件:当有新的 commit 被 push 到 main 分支时自动触发
**注意:**这里的scrects的变量必须与你创建的名称一致,否则在连接EC2时候,会出现ssh为空等问题
name:AWS EC2 Deployon:push:branches:-mainjobs:deploy:name:Deploy to EC2runs-on:ubuntu-latest# 必须指定在 ubuntu-latest 虚拟环境中运行构建steps:-name:Checkout code# 第一步:拉取仓库代码uses:actions/checkout@v3-name:Setup SSH# 第二步:借助社区经典的 SSH 动作组件加载我们的私钥uses:webfactory/ssh-agent@v0.7.0with:ssh-private-key:${{secrets.EC2_SSH_KEY}}-name:Deploy application# 第三步:通过 SSH 登录云服务器,串行执行自动化部署命令run:|ssh -o StrictHostKeyChecking=no ${{ secrets.EC2_USER }}@${{ secrets.EC2_HOST }} << 'EOF'echo "开始进入云端项目代码目录..." cd ~/ChatBot_Telegram/Chatbot echo "拉取 GitHub 远程主分支最新代码..." git pull origin main echo "激活云端虚拟环境并更新依赖清单..." source venv/bin/activate pip install-r requirements.txt echo "【核心防御】安全清理旧的机器人后台进程,防止多实例 Token 抢占冲突..." pkill-f "python chatbot.py"||true echo "在虚拟环境内利用 nohup 重新在后台拉起新版机器人程序..." nohup ~/ChatBot_Telegram/Chatbot/venv/bin/python chatbot.py>app.log 2>&1& echo "云端自动化部署结束!" EOF保存文件。
04 触发自动部署与流水线测试
见证奇迹的时刻到了。我们现在要在本地做一点小修改,并把代码推送到云端。
- 修改代码:打开你本地的
chatbot.py,把机器人的某些回复逻辑稍微改一下(比如在回复前加上一句[云端自动化更新版]:),保存文件。 - 提交并推送:在本地 Git Bash 中执行我们最熟悉的三连:
gitadd.gitcommit-m"Add GitHub Actions workflow for EC2 deployment"#如果之前修改了requirements.txt文件请先pullgitpullgitpush origin main- 观看自动化演出:立刻打开你的 GitHub 仓库网页,点击上方的Actions选项卡。
你会看到一个黄色的圆圈正在旋转,这就是 GitHub 正在按照你的剧本,自动登录服务器、拉取代码、杀掉旧进程并启动新版本。
当圆圈变成绿色的对勾 (✅)时,说明部署成功!
部署成功后,
您的聊天机器人将在 EC2 实例上运行。
请使用以下命令验证在 EC2 实例中运行的聊天机器人的 Python 进程:
ssh-i"keypair_chatbot.pem(你的pem文件名)"ec2-user@(你的EC2 DNS)ps-ef|greppython您应该看到以下输出:
ec2-user372711006:02 ? 00:00:00 /home/ec2user/chatbot_comp7940/venv/bin/python chatbot.py现在,立刻拿出手机给机器人发消息,如果它回复了你刚刚修改的新内容,恭喜你,你的 CI/CD 工业级流水线已经全线贯通!
注意使用完毕后,记得关闭EC2,防止流量浪费!!
05 踩坑实录:自动化部署中的那些致命报错
自动化部署虽然爽,但在调试配置阶段,极其容易出现以下三个让人抓狂的问题:
❌ 错误一:Telegram API 报错Conflict: terminated by other getUpdates request
- 报错现象:通过 Actions 部署成功后,机器人突然毫无反应。进入云端用
cat chatbot.log查看日志,发现满屏幕的Conflict: terminated by other getUpdates...红色报错。 - 原因分析:这是 Telegram 机器人的专属大坑。由于前几次测试时我们在后台启动了机器人,但在执行新的部署脚本时,没有把旧的进程杀掉就直接启动了新的。导致两份一样的代码在云端同时运行,它们在疯狂争抢同一个 Bot Token。Telegram 官方服务器发现有两个客户端同时拉取数据,就会触发安全机制,直接把双方都强制踢下线。
- 解决方案:在 YAML 脚本的
script部分,在启动新进程之前,必须加上这一行“杀手”命令:pkill -f chatbot.py || true。这句命令的意思是:精准狙击并杀掉所有名字里带chatbot.py的后台进程,清空战场后再启动新代码。
❌ 错误二:Actions 日志提示git pull: Please commit your changes or stash them
- 报错现象:GitHub Actions 运行失败打红叉。点开详情日志发现卡在
git pull这一步,提示有未提交的更改。 - 原因分析:这是因为你在上一章中,为了修复依赖问题,直接在云端 EC2 里面修改过文件(比如手动改过
requirements.txt或config.ini),导致云端的代码状态与 GitHub 上的状态发生了分叉和冲突,Git 为了保护你的文件拒绝了直接覆盖。 - 解决方案:登录云端服务器,进入项目目录,执行强制覆盖命令,让云端彻底向 GitHub 对齐:
gitpull(注:如果你的config.ini因为被.gitignore保护而没有被影响,那么上述操作不会删除你的配置文件,可以放心执行。)
❌ 错误三:YAML 解析错误
- 报错现象:刚把代码 push 上去,Actions 连跑都没跑就直接报错。
- 原因分析:YAML 格式对空格有极度严格的要求(比如
uses:和with:的相对位置)。可能在复制粘贴时多打了一个空格,或者不小心按了Tab键。 - 解决方案:强烈推荐在本地使用 VS Code 等现代编辑器,它们通常会自带 YAML 语法高亮和缩进对其线检查。确保每一层级的缩进都是标准的2 个空格。
❌ 错误四:SSH Key 解析错误
报错现象:刚把代码 push 上去,Actions 出现SSH错误,显示ssh为空。
原因分析:在deploy.yml文件中没有把secrets的属性改为在github中创建的变量
解决方案:修改变量对应github上的变量名称,然后重新push上github。
💡 06. 深度思考题与参考答案 (Reflection & Solutions)
自动化部署看似神奇,但本质依然是一行行脚本的执行。请结合本章的实战经历,思考以下三个涉及架构、安全与排错的核心问题:
❓ 思考题 1:CI/CD 的本质与价值
题目: 请用你自己的语言简述什么是 CI/CD?在我们这个聊天机器人项目中,GitHub Actions 具体扮演了什么角色?它替我们节省了哪些传统运维中的手动操作步骤?
✅ 参考答案:
CI/CD 的本质:CI(持续集成)指代码提交后自动进行构建和测试;CD(持续部署/交付)指测试通过后自动将代码发布到生产服务器。它的本质是将人类枯燥、重复且易错的手动发布流程,转化为由机器严格执行的自动化流水线。
扮演的角色:GitHub Actions 扮演了一个“不知疲倦的云端机器人运维管家”或者说“自动化脚本执行引擎”。
节省的步骤:它让我们告别了以下繁琐的手动闭环:
- 打开终端输入 SSH 命令及私钥登录云服务器 ➔
- cd 切换到项目目录 ➔
- 手动敲 git pull 同步代码 ➔
- 激活 Python 虚拟环境 ➔
- 运行 pip install 检查并更新依赖 ➔
- 查找并 kill 掉旧的机器人进程 ➔
- 再次用 nohup 挂载新进程。现在这一切只需本地的一句 git push 即可全自动完成。
❓ 思考题 2:云原生时代的安全底线
题目: 在编写 deploy.yml 部署脚本时,为什么我们绝对不能图省事,直接把 EC2 的公网 IP 地址、用户名和极其私密的 .pem 密钥以明文(Plaintext)的形式写在 YAML 文件里?配置 GitHub Secrets 的根本原理和作用是什么?
✅ 参考答案:
明文硬编码的毁灭性后果:deploy.yml 文件是存放在项目代码库的 .github/workflows 目录下的,它与你的业务代码一样受 Git 版本控制。如果直接写明文,一旦你的仓库是公开的(Public),或者未来代码泄露,任何人都能直接拿到你云服务器的最高控制权(Root 权限)。黑客可以轻易登录你的 AWS 注入勒索病毒、盗取隐私数据或利用你的算力疯狂挖矿,导致你背负巨额的云服务账单。
GitHub Secrets 的原理与作用:GitHub Secrets 相当于一个完全脱离版本控制的“云端保险箱”。它的作用是环境变量的动态安全注入。存入 Secrets 的密钥会被高强度加密,只有在 Actions 流水线运行的短暂瞬间,才会被提取到内存中供脚本使用,并且一旦使用完毕立即销毁。同时,它会自动在所有的部署日志中将密码脱敏(显示为 ***),彻底斩断了密钥泄露的途径。
❓ 思考题 3:流水线“假阳性”排错实战
题目: 假设你刚 push 了一段新代码,GitHub 网页端的 Actions 流水线跑完后显示了绿色的对勾(✅ 部署成功),但你拿出手机给 Telegram 机器人发消息,它却毫无反应或者依然在回复旧版本的逻辑。请结合 Linux 后台运行机制,推理一下最有可能导致这种现象的原因是什么?你应该如何去排查?
✅ 参考答案:
这属于典型的**“流水线假阳性(False Positive)”**。Actions 显示绿勾,仅仅代表 YAML 脚本里的 Bash 命令行执行完毕且没有抛出致命错误退出的状态码,但这并不等同于你的 Python 业务代码成功运行了!
可能原因 1:旧进程未被杀死(端口/Token 抢占冲突)。如果在 YAML 脚本里漏写了 pkill -f chatbot.py,会导致新代码虽然下载了,但原本在后台运行的旧进程依然存活。新进程由于与旧进程抢占同一个 Telegram API 端口或 Token 而启动失败(或双双阵亡),此时你调用的依然是没死透的旧机器人。
可能原因 2:Python 代码自身存在致命的语法错误。因为我们在 YAML 最后一行使用的是 nohup python chatbot.py > chatbot.log 2>&1 &。请注意结尾的 & 符号!它代表把程序丢到后台执行,Bash 脚本一执行完这句就会立刻认为任务完成并宣告部署成功。此时,如果你的 Python 代码里少写了一个括号导致瞬间崩溃,Actions 是察觉不到的。
排查方案:立刻通过 SSH 登录 EC2 服务器,进入项目目录,执行 cat chatbot.log 命令查看你重定向的日志文件,里面一定记录了 Python 抛出的具体报错追踪栈(Traceback)
📝 文章摘要
本文是《从零搭建聊天机器人》系列教程的第五章,核心目标是利用GitHub Actions为部署在 AWS EC2 上的 Telegram 聊天机器人构建一套完整的CI/CD(持续集成与持续部署)自动化运维流水线。
核心内容总结如下:
- 解决后台长驻问题:通过
nohup命令让机器人在 SSH 会话关闭后依然能在云端后台持久运行,并解释了其原理(忽略SIGHUP信号)。 - 安全凭证管理:详细指导如何在 GitHub 仓库的 Secrets 中安全配置 EC2 服务器的连接信息(主机、用户名、SSH 私钥),避免敏感信息硬编码在代码中。
- 构建自动化流水线:提供了完整的
deploy.yml工作流脚本,该脚本在代码推送到main分支时自动触发,执行拉取代码、更新依赖、杀死旧进程、重启新服务等一系列部署操作。 - 实战测试与验证:引导读者通过修改代码并推送,触发自动化部署,并通过检查 GitHub Actions 运行状态和服务器进程来验证部署是否成功。
- 常见错误与排错:总结了自动化部署中可能遇到的四大典型问题(如进程冲突、Git 合并冲突、YAML 格式错误、SSH 密钥配置错误),并提供了具体的解决方案和排查思路。
- 深度思考:通过三个思考题,引导读者深入理解 CI/CD 的价值、GitHub Secrets 的安全原理,以及如何排查“部署成功但服务未更新”的“假阳性”问题。
最终成果:实现“代码一推,服务起飞”的自动化目标,将传统繁琐的云端手动更新流程(登录、拉取、重启)完全自动化,显著提升开发效率和部署可靠性。
。
