Linux 服务器部署 QQ 机器人:NapCat + NoneBot2 + GsCore + Caddy

2026 年 6 月 19 日

2516 字

13 分钟

技术

Linux 服务器部署 QQ 机器人:NapCat + NoneBot2 + GsCore + Caddy

这次我想在 Linux 服务器上把一套 QQ 机器人真正跑稳,于是最后落下来的方案是 NapCat + NoneBot2 + GsCore,前面再加一层 Caddy 做 HTTPS 和反向代理。思路并不复杂,但真正一路走下来,问题几乎都出在那些“看起来只是小细节”的地方:终端编码、脚手架命令、Web 后台监听地址、证书验证,甚至是最基础的 DNS。

这篇文章把整套过程整理成一份可以直接照着走的教程,也把我们这次遇到的坑和修法一并写下来。它不是“理想环境下一次成功”的笔记,而是更接近真实部署现场的版本。

最终架构

我们最终采用的是下面这条链路:

QQ / 群消息
  -> NapCat
  -> NoneBot2
  -> nonebot-plugin-genshinuid
  -> GsCore
  -> 具体业务插件(如 GenshinUID)

如果需要把后台安全地开放到公网,则再额外加一层:

Browser
  -> Caddy (HTTPS / reverse_proxy)
  -> NapCat WebUI / GsCore WebConsole

这里我有两个实际建议:

  1. 机器人消息链路和后台管理链路要分开理解。
  2. 60998765 不要直接裸露到公网,尽量只让 Caddy 回源到本机端口。

组件职责

  • NapCat:负责协议端和 QQ 登录,本质上是机器人和 QQ 之间的入口。
  • NoneBot2:负责 Bot 框架本身,接收 OneBot 事件、分发插件、组织逻辑。
  • GsCore:早柚核心,负责统一连接和插件生态。
  • nonebot-plugin-genshinuid:NoneBot2 侧连接 GsCore 的官方插件。
  • Caddy:负责自动 HTTPS、反向代理,以及把后台入口放到统一域名下。

环境准备

本文默认:

  • 系统是 Ubuntu / Debian 系 Linux
  • 你有 rootsudo 权限
  • 服务器已经可以联网
  • 你已经准备好一个用于登录的 QQ 账号
  • 你有一个域名,并且后面会用 Cloudflare 管理 DNS

建议目录结构像这样:

~/qqbot        # NoneBot2 项目
~/gsuid_core   # GsCore 本体

第一步:安装 NapCat

NapCat 官方 Linux 安装器可以直接使用:

curl -o napcat.sh https://nclatest.znin.net/NapNeko/NapCat-Installer/main/script/install.sh
bash napcat.sh --tui

安装后,通常可以通过下面的命令再次进入它的 TUI:

sudo napcat

我们遇到的第一个坑:NapCat Shell 乱码

刚打开 Napcat Shell 时,我们看到的是一堆类似 ~@~A~M~U 的乱码,而不是正常中文界面。这不是 NapCat 坏了,而是典型的终端字符集和 TERM 设置问题。

先检查:

locale
echo $LANG
echo $TERM

如果不是 UTF-8,可以先临时修正:

export LANG=zh_CN.UTF-8
export LC_ALL=zh_CN.UTF-8
export TERM=xterm-256color
sudo napcat

如果服务器没有对应 locale,再补:

sudo apt update
sudo apt install -y locales
sudo locale-gen zh_CN.UTF-8
sudo update-locale LANG=zh_CN.UTF-8

如果你不想使用中文 locale,用通用的 C.UTF-8 也可以:

export LANG=C.UTF-8
export LC_ALL=C.UTF-8
export TERM=xterm-256color
sudo napcat

登录 NapCat WebUI

NapCat 的 WebUI 默认通常在 6099 端口。启动后,可以在日志里看到带 token 的访问地址。登录后完成 QQ 扫码,并修改好 WebUI 密码。

第二步:创建 NoneBot2 项目

先建立 Python 虚拟环境:

mkdir -p ~/qqbot
cd ~/qqbot
python -m venv .venv --prompt nonebot2
source .venv/bin/activate

安装基础依赖:

pip install "nonebot2[fastapi]"
pip install nonebot-adapter-onebot

创建 .env

HOST=127.0.0.1
PORT=8080
ONEBOT_ACCESS_TOKEN=改成你自己的长随机串
COMMAND_START=["/"]
COMMAND_SEP=["."]

创建 bot.py

import nonebot
from nonebot.adapters.onebot.v11 import Adapter as OneBotV11Adapter

nonebot.init()

driver = nonebot.get_driver()
driver.register_adapter(OneBotV11Adapter)

if __name__ == "__main__":
    nonebot.run()

启动试一下:

source .venv/bin/activate
python bot.py

第三步:让 NapCat 连到 NoneBot2

在 NapCat 的网络配置里,新建一个 WebSocket 客户端,把它指向:

ws://127.0.0.1:8080/onebot/v11/ws

Token 要和 .env 中的 ONEBOT_ACCESS_TOKEN 保持一致。

如果出现 403,优先检查 token 是否一字不差。

第四步:安装 GsCore

根据 GsCore 官方文档,把它单独安装在 Bot 目录的同级:

cd ~
git clone https://github.com/Genshin-bots/gsuid_core.git --depth=1 --single-branch
cd gsuid_core

官方更推荐 uv

uv python install 3.13
uv sync --python 3.13
uv run python -m ensurepip

启动 GsCore:

uv run core

首次启动后,会生成:

~/gsuid_core/data/config.json
~/gsuid_core/data/core_config.json

第五步:在 NoneBot2 里接入 GsCore

GsCore 在 NoneBot2 侧的官方插件是 nonebot-plugin-genshinuid

我们遇到的第二个坑:nb 命令不存在

我们一开始按文档执行:

nb plugin install nonebot-plugin-genshinuid

结果报错:

-bash: nb: command not found

原因不是项目坏了,而是环境里没装 nb-clinb 不是 Python 自带命令,它是 NoneBot 的脚手架。

有两种解法:

解法 A:补齐 nb-cli

cd ~/qqbot
source .venv/bin/activate
pip install nb-cli
nb plugin install nonebot-plugin-genshinuid

解法 B:直接用 pip

如果你已经手写了 bot.py,其实直接安装插件通常就够了:

cd ~/qqbot
source .venv/bin/activate
pip install nonebot-plugin-genshinuid

这次我们更推荐第二种,因为路径更短,也更少引入额外依赖。

给 NoneBot .env 加上 GsCore 配置

在原有 .env 下面继续补:

gsuid_core_ws_token=123
gsuid_core_host=localhost
gsuid_core_port=8765
gsuid_core_botid=NoneBot2

配置 GsCore 的 config.json

编辑:

~/gsuid_core/data/config.json

至少确认这些值:

{
  "HOST": "localhost",
  "PORT": "8765",
  "masters": ["你的QQ号"],
  "WS_TOKEN": "123",
  "TRUSTED_IPS": ["127.0.0.1"]
}

注意:

  • WS_TOKEN 要和 NoneBot .env 里的 gsuid_core_ws_token 一致
  • masters 填你自己的 QQ 号,否则后面很多核心命令你没有权限执行

第六步:安装业务插件

GsCore 本体只能算平台,真正的功能还需要业务插件。

如果你已经把自己加入 masters,可以在聊天里让 GsCore 直接安装:

core安装插件GenshinUID

如果你更想手动装:

cd ~/gsuid_core/plugins
git clone -b v4 https://github.com/KimigaiiWuyi/GenshinUID.git --depth=1 --single-branch

安装完记得重启 GsCore。

第七步:访问 GsCore 后台

GsCore 的后台是它的 Web Console,默认路径是:

http://127.0.0.1:8765/app

如果你在本机浏览器访问,这通常就够了。

我们遇到的第三个坑:外网访问 GsCore 返回 502

我们在公网直接访问时拿到了 HTTP ERROR 502,后来看到 GsCore 的提示日志:

WebConsole挂载于本地, 如想外网访问请修改data/config.json中host为0.0.0.0!

这说明后台只监听本机,外部访问当然进不来。最直接的修法是把:

"HOST": "localhost"

改成:

"HOST": "0.0.0.0"

但更好的做法是不要直接把 8765 裸暴露出去,而是让 GsCore 继续只监听本机,再交给 Caddy 反向代理。

第八步:用 Caddy 暴露 NapCat 和 GsCore 后台

从实际安全性上看,把 60998765 直接开公网不是个好习惯。更稳妥的方式是:

  1. NapCat WebUI 和 GsCore WebConsole 只监听本机
  2. 服务器只对外开放 80/443
  3. Caddy 统一做 HTTPS 和反向代理

安装 Caddy

在 Ubuntu / Debian 上可以这样装:

sudo apt update
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install -y caddy

推荐的回源方式

让后端都只监听本机:

  • NapCat WebUI -> 127.0.0.1:6099
  • GsCore WebConsole -> 127.0.0.1:8765

然后写 /etc/caddy/Caddyfile

{
	email yourmail@example.com
}

napcat.example.com {
	reverse_proxy 127.0.0.1:6099
}

gscore.example.com {
	reverse_proxy 127.0.0.1:8765
}

检查并重载:

sudo caddy fmt --overwrite /etc/caddy/Caddyfile
sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl restart caddy
sudo systemctl status caddy

第九步:我们遇到的第四个坑:Caddy 证书申请失败

Caddy 启动后本身是正常的,但日志里一直在报 challenge failed。最后发现问题并不在 Caddy,而是更前面的基础设施:我忘了去 Cloudflare 里添加 DNS 记录。

这类错误很典型,通常是下面几种之一:

  1. 域名没有正确解析到当前服务器
  2. 80/443 没有对公网放通
  3. 其他程序占用了 80443
  4. DNS 刚改完还没生效

排查命令

查看 Caddy 日志:

sudo journalctl -u caddy -n 80 --no-pager

检查域名解析:

dig +short napcat.你的域名 A
dig +short gscore.你的域名 A

检查监听情况:

ss -lntp | grep ':80\|:443'

检查防火墙:

sudo ufw status

如果你在 Cloudflare 里忘了加 DNS,那么 Caddy 的 ACME 验证当然不可能成功。这个问题很“基础”,但也最常见。

最终建议的安全姿势

如果只是自己使用后台,我建议这样收口:

  1. 60998765 不对公网开放
  2. 只开放 80/443
  3. NapCat 和 GsCore 都只监听本机
  4. Caddy 统一反代
  5. 后台本身保留 token / 强密码
  6. 如果条件允许,再加 IP 白名单或额外认证层

这里要特别提醒一点:邮箱不是认证机制。它只是 Caddy 申请证书时的联系邮箱,不是登录保护。真正保护你后台的,是 HTTPS、反代边界、后台密码、token,以及你有没有把源端口直接开到公网。

推荐的启动顺序

部署完成后,推荐按这个顺序启动和排查:

  1. NapCat
  2. NoneBot2
  3. GsCore
  4. 业务插件
  5. Caddy

如果有问题,也按这条链路往后看:

QQ 登录是否正常
-> OneBot WebSocket 是否正常
-> NoneBot 是否启动
-> GsCore 是否已连接
-> 插件是否已加载
-> Web 后台是否可访问
-> HTTPS / DNS / Caddy 是否正常

这次部署里最值得记住的四件事

1. TUI 乱码通常不是程序坏了,而是终端环境不对

先看 LANGLC_ALLTERM,别急着怀疑软件本身。

2. nb 命令不存在,往往只是没装 nb-cli

如果你走的是手写 bot.py 路线,很多时候直接 pip install 插件反而更省事。

3. 后台只绑定本地时,公网访问失败是正常现象

看到 host=localhost 或“挂载于本地”的提示,就不要继续往外网层面猜了。

4. HTTPS 证书失败,很多时候不是代理错了,而是 DNS 没配

反代、TLS、证书这些东西看起来高级,但最常见的故障点往往仍然是最基础的那层。

参考文档

结语

这套方案最后跑通时,我最强烈的感受并不是“终于把机器人装好了”,而是这类部署工作的难点从来都不只是安装命令本身。真正决定你后面省不省心的,是边界有没有收清楚:协议端和框架端是不是分离,后台是不是裸露在公网,域名是不是已经指对,日志是不是能帮你快速定位问题。

把这些边界收好之后,NapCat + NoneBot2 + GsCore + Caddy 其实是一套非常顺手的组合。它不算最轻,也不算最花哨,但足够清晰,足够稳定,也足够适合长期维护。

Linux 服务器部署 QQ 机器人:NapCat + NoneBot2 + GsCore + Caddy
https://blog.shishishi3.com/blog/linux-qq-bot-napcat-nonebot-gscore-caddy/
作者
豕豕豕
发布时间
2026 年 6 月 19 日
许可协议
CC BY-NC-SA 4.0

即将打开 RSS Feed

RSS 是给订阅器读取的 XML Feed,浏览器直接打开通常会看到 XML 文本,这属于正常现象。

为避免误触和误导跳转,这里会在 5 秒确认后再进入当前语言的 Feed 页面。

输入关键词开始搜索