从零给 QQ 挂一个 AI 机器人(一):Docker 部署 AstrBot + NapCat,含腾讯风控掉线排查
📌 《从零给 QQ 挂一个 AI 机器人》系列 · 第 1 篇(共 2 篇)
作者:AVA
环境:国内云服务器(Ubuntu)+ Docker Compose + AstrBot 4.28.2 + NapCat⚠️ 看之前先注意两件事:本文里所有 IP / QQ 号 / token 都替换成了占位符,你照着做时换成自己的。另外第 6 节那个坑会直接把机器人搞掉线,建议先扫一眼再动手。
这套东西到底由几个部分组成
第一次搭 QQ 机器人最容易懵的就是:「AstrBot 和 NapCat 是什么关系,为什么要装两个容器?」
一句话说清分工:
- NapCat = 协议端。手机 QQ 能聊天靠的是腾讯的私有协议,NapCat 的作用就是把这套协议翻译成标准的 HTTP / WebSocket 接口。它本身不含任何 AI 能力,也完全不懂你说的话是什么意思。
- AstrBot = 大脑。它接收消息、调大模型、决定回什么,再把要发的内容交回给协议端。
两者之间用 OneBot v11 这个事实标准通信——这也是为什么 NapCat 不止能配 AstrBot,换别的框架同样能用。
连接方式:为什么选「反向 WebSocket」
OneBot v11 有两种连法,方向正好相反:
| 方式 | 谁主动连谁 | 适用场景 |
|---|---|---|
| 正向 WS | 框架 → NapCat | 框架和协议端在同一台机器、网络简单 |
| 反向 WS | NapCat → 框架 | 推荐。协议端主动连,框架只需开个端口等着 |
我们选反向,配置上更省事:AstrBot 当服务端监听 6199,NapCat 当客户端主动连过来。
⚠️ 这里有个关键细节:连的地址要写容器名而不是 IP——
ws://astrbot:6199/ws
因为两个容器在同一个 Docker 网络里,Docker 内置的 DNS 能把容器名解析成 IP。写死 IP 的话,容器重建换 IP 就断。
部署
核心是一份 docker-compose.yml:
services:
astrbot:
image: soulter/astrbot:latest
container_name: astrbot
restart: unless-stopped
ports:
- "127.0.0.1:6185:6185" # WebUI,只绑本机
volumes:
- ./astrbot/data:/AstrBot/data
napcat:
image: mlikiowa/napcat-docker:latest
container_name: napcat
restart: unless-stopped
environment:
- TZ=Asia/Shanghai
- WEBUI_TOKEN=<你自己的-token>
- ACCOUNT=<机器人的QQ号> # ← 别省,见第 6 节
- QQ_APP_ARGS=--no-sandbox
ports:
- "127.0.0.1:6099:6099" # NapCat WebUI,只绑本机
volumes:
- ./napcat/QQ:/app/.config/QQ # 登录态 + 设备指纹,删了就重新扫码
- ./napcat/config:/app/napcat/config
- ./napcat/logs:/app/napcat/logs
两个 restart: unless-stopped 是必须的——服务器重启后要能自己拉起来,不能依赖任何人的电脑开着。
打开管理界面:SSH 隧道
注意上面两个端口都写的是 127.0.0.1:xxxx,不是 0.0.0.0。这是故意的:管理界面公网碰不到,只能走隧道进去。
ssh -L 6185:127.0.0.1:6185 -L 6099:127.0.0.1:6099 root@<你的服务器IP>
然后本地浏览器开 http://localhost:6185。
⚠️ 隧道只影响「你能否打开管理界面」,跟机器人本身无关——关掉隧道,机器人照样 24 小时在线。
踩坑合辑
这几个都是实测撞过的,按顺序排:
① 国内服务器装 Docker 会失败
curl: (35) Recv failure: Connection reset by peer
get.docker.com 在国内基本连不上。换清华源:
mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu
(如果正好是腾讯云机器,https://mirror.ccs.tencentyun.com 这个内网加速器更快,但只在腾讯云内网可用。)
② AstrBot 没有默认密码了
老教程里写的 astrbot / astrbot 早就没了,新版启动时会生成一个随机强密码,只在启动日志里打印一次。第一次部署记得先看一眼日志再关窗口:
docker compose logs astrbot | head -60
忘了也不至于重装——去 data/cmd_config.json 里删掉 dashboard 下面那六个凭据字段,重启会重新生成。
③ 用 FinalShell 粘贴长命令会吃掉结尾
docker-compose-plugin 粘上去变成 docker-compose-plugi,然后 apt 报 Unable to locate package。报「找不到包」时先怀疑这个,别去折腾源。长命令拆成两条敲。
④ Windows 上写 .bat 启动脚本,窗口一闪就关
罪魁祸首是 > 和 < 在 cmd 里是重定向符。echo 里想输出尖括号必须写成 ^> ^<,否则脚本静默死掉——不报错、不暂停、直接消失。
另外 .bat 里有中文要用 GBK 存(CMD 默认 936 代码页),但用 VS Code 这种 UTF-8 编辑器打开会显示乱码,看着像没写完。最省事的做法是脚本里干脆别用中文。
⑤ WebSocket 死活连不上
先确认 AstrBot 侧监听地址是 0.0.0.0 而不是 127.0.0.1(容器里的 127.0.0.1 是它自己,别的容器连不进来),再确认端口号两边一致。
🔴 第 6 节:重建 NapCat 容器 = QQ 掉线 + 腾讯风控
这是全文最值钱的一段,也是踩得最惨的一段。
改完 docker-compose.yml 执行 docker compose up -d,容器被重建(不是重启)。启动日志变成了这样:
正在快速登录 <机器人QQ号>
快速登录错误: 你的用户身份已失效,为保证账号安全,请你重新登录。
快速登录不行就转扫码。扫码之后:
[Core] [Login] 二维码已被扫描,等待确认...
[Core] [Login] Login Error , ErrInfo: [1,{"account":"...","serverErrorCode":168,
"message":"你的账号近期存在安全风险,部分功能使用受限,
请登录最新手机QQ并根据提示恢复账号使用。"}]
机器人彻底离线。
为什么会这样
腾讯把「容器重建」识别成了一次新设备 / 新环境登录,直接触发账号级风控。错误码 168 是账号被限制,不是你的配置写错了。
👉 所以:在服务器上怎么改配置都绕不过去。 别去翻 NapCat 和 AstrBot 的文档,浪费一晚上。
唯一的解法
机主亲自在最新版手机 QQ 上登录这个机器人账号,按提示走完安全验证(短信 / 人脸之类),然后回来重新扫一次码。
⚠️ 注意这里有个坑:缓存的登录票据已经作废了,所以快速的「免扫码登录」那条路回不来,必须重新扫码。第一遍扫大概率还是 168,那是风控没解除,不是操作错了。
两个经验
- 能不重建容器就不重建。 真要改 NapCat 的配置,先想清楚会不会触发重建,并且跟能立刻做手机验证的人约好时间——不然机器人就挂在那儿了。
ACCOUNT环境变量一定要配。 不配的话,容器重启时 NapCat 不知道要登哪个号,会退化成无参启动,白白多一步。配上之后日志里会显示「正在快速登录 <QQ号>」,省心很多。
最后一句实话
云服务器的 IP 上登录 QQ,被风控是常态,不是你做错了什么。真要做长期稳定的机器人,用一个养过一段时间、有正常使用记录的老号,比什么配置优化都管用。
怎么算部署成功
看到这一行就通了:
[Core] [INFO] [aiocqhttp.aiocqhttp_platform_adapter:107]: aiocqhttp(OneBot v11) 适配器已连接。
然后拿另一个 QQ 号私聊机器人,能正常回复,整条链路就闭环了。
补充 ①:(自己起个小标题)
🔲 留给你写:两三句话就行——比如你为什么要搭这个机器人、原本打算让它干什么。写不出来就把这一整节删掉,不影响阅读。
补充 ②:(自己起个小标题)
🔲 留给你写:这个坑里你当时的反应,或者你机器上遇到的不一样的地方。
📖 本系列共 2 篇,下一篇:02 给它装一双手 —— 让机器人自己下载文件、还能发回给你
代码与环境基于 AstrBot 4.28.2 实测,有问题欢迎评论区交流。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)