装个 sqlite3 给我返回 502,这只是开始
机器人的数据库开始报 I/O 错误,SQLite 在频繁读写下确实容易这样,我决定换 PostgreSQL。
第一步是导出数据,缺工具:
sqlite3: command not found
那就装。然后:
Err:4 http://mirrors.tencentyun.com/ubuntu noble InRelease
502 Bad Gateway [IP: 127.0.0.1 7890]
apt 在走本机 7890 端口的代理,而那个代理当时是死的,于是连访问腾讯云自己的内网镜像都失败。我第一反应是镜像站抽风,其实是自己绕自己。
unset http_proxy https_proxy 没用,代理写死在配置文件里(/etc/apt/apt.conf.d/ 下面那个)。绕过去:
apt -o Acquire::http::Proxy=false update
apt -o Acquire::http::Proxy=false install -y sqlite3
导完数据开始改配置。编辑完 data/cmd_config.json 重启,报:
JSONDecodeError: Unexpected UTF-8 BOM ... line 1
BOM。有些编辑器保存 UTF-8 文件时会在开头塞三个字节 EF BB BF,Python 的 json 见到就报错,而你在编辑器里看它完全正常。我盯着文件看了很久,什么都没看出来。
去掉:
sed -i '1s/^\xEF\xBB\xBF//' /root/astrbot/data/cmd_config.json
然后是最费时间的一步。我把数据库配置写得整整齐齐:
"db": {
"type": "postgresql",
"host": "...",
"port": 5432
}
重启,日志里就一句:
Config key removed: db
它不认这个配置块,给我删了。 没有报错,没有提示,就一句"已移除"。我反复检查 JSON 语法、缩进、字段名,全都对,它就是不读。
折腾了很久,最后改用环境变量,这也是最终生效的方案:
docker run -d --name astrbot \
-e ASTRBOT_DATABASE_TYPE=postgresql \
-e ASTRBOT_DATABASE_HOST=172.17.0.1 \
-e ASTRBOT_DATABASE_PORT=5432 \
-e ASTRBOT_DATABASE_USER=astrbot \
-e ASTRBOT_DATABASE_NAME=astrbot \
soulter/astrbot:latest
数据库单独跑官方镜像,数据挂宿主机目录:
postgres:
image: postgres:15
volumes:
- /root/postgres_data:/var/lib/postgresql/data
切过去之后,之前的 I/O 报错没再出现。
这三件事我后来一起想过,问题都出在同一处:我改的东西没被读到。
apt 在走代理而不是直连镜像;文件开头有三个字节的 BOM 让解析直接失败;db 这个键根本没被程序读取。三次都不是"我写得不对",而是"我写的地方不是它读的地方"。
所以后来我改完配置的第一件事变了:不再急着看结果,先找证据证明改动生效了——看日志有没有读到这个配置、看进程有没有真正加载。这步几十秒,能省下我那天晚上的几个小时。