LibreChat 对话历史存在哪——换台机器部署还能接着聊吗?

文章导读
换机器部署 LibreChat 后能不能接着聊,关键不在前端页面,而在部署时用的数据库数据卷有没有跟着搬。LibreChat 通常把会话和消息写进 MongoDB,数据库容器再把数据落在挂载卷里;只复制项目代码或重新拉镜像,新环境一般看不到旧会话。要判断该备份什么,可以先从编排文件确认 MongoDB 服务的卷挂载点,再用数据库客户端确认 conversations 和 messages 这类集合
📋 目录
  1. 从编排文件里定位数据库服务与数据卷
  2. 用数据库客户端确认会话与消息存放在哪
  3. 备份数据卷后在新机器恢复并登录查看
  4. 确认用户级密钥的存放位置决定是否重填
A A

换机器部署 LibreChat 后能不能接着聊,关键不在前端页面,而在部署时用的数据库数据卷有没有跟着搬。LibreChat 通常把会话和消息写进 MongoDB,数据库容器再把数据落在挂载卷里;只复制项目代码或重新拉镜像,新环境一般看不到旧会话。要判断该备份什么,可以先从编排文件确认 MongoDB 服务的卷挂载点,再用数据库客户端确认 conversations 和 messages 这类集合里确有记录,最后核对用户级密钥和加密配置是否随环境一起迁移。登录信息本身通常由 JWT 和数据库用户记录决定,迁移数据库后旧账号一般还能登录,但用户自己填的模型密钥能否继续使用,要看加密密钥和环境变量有没有保持一致。

LibreChat 的对话历史一般不在浏览器本地,而是保存在部署侧 MongoDB 数据卷中。换机器时,先停写并备份数据库卷,再在新机恢复同一卷;同时保持原环境里的 JWT 与凭据加密配置一致。验证方式是登录后能看到旧会话,并能成功发出一条新消息。若只搬代码不搬数据卷,历史会丢;若搬了数据卷但改了加密密钥或漏填环境变量,用户级密钥可能失效,需要重填。具体路径和字段以你的编排文件与数据库实际内容为准。

从编排文件里定位数据库服务与数据卷

先确认 LibreChat 连接的是哪种 MongoDB。打开 docker-compose.yml 或 compose.yaml,找 services 下名为 mongodb、mongo 或 database 的服务,再看它的 volumes 和 environment。如果 volumes 写成 ./data/mongodb:/data/db,历史数据就在项目目录下的 data/mongodb;如果写成 mongodb_data:/data/db,则在一个命名卷里,卷名可能带 compose 项目前缀。environment 里的 MONGO_URI 决定应用连哪个库,若指向外部 MongoDB,迁移目标就不是本地卷,而是外部数据库的备份。

可以用下面几组命令把挂载点从编排文件落到实际容器。容器名以 docker compose ps 的输出为准,不要直接照抄示例。

grep -n -A 8 'mongodb' docker-compose.yml
docker compose ps
docker inspect -f '{{json .Mounts}}' librachat-mongodb-1
docker volume ls | grep -i mongo
docker volume inspect <实际卷名>

如果 docker inspect 看到 Source 是宿主机目录、Destination 是 /data/db,说明 MongoDB 数据落在该目录;如果 Source 是命名卷,Destination 仍是 /data/db,就要按卷名备份。确认挂载点时不要只凭服务名猜,因为不同 compose 文件可能把数据目录映射到其他路径。

用数据库客户端确认会话与消息存放在哪

连接 MongoDB 后,查看实际数据库名和集合。LibreChat 默认库名常见为 LibreChat,但以 MONGO_URI 或连接后的 db.getName() 为准。会话标题、参与者等信息通常在 conversations 集合,消息正文通常在 messages 集合;用户记录和用户级密钥可能在 users 集合。集合名可能随版本或配置变化,所以先 show collections 看实际名称。

LibreChat 对话历史存在哪——换台机器部署还能接着聊吗?
docker exec -it <mongo容器名> mongosh
# 若启用了认证,用下面形式
docker exec -it <mongo容器名> mongosh -u <用户名> -p <密码> `--authenticationDatabase` admin
use LibreChat
show collections
db.conversations.findOne()
db.messages.findOne()
db.messages.countDocuments({})
db.users.findOne({}, { email: 1 })

看到 conversations 和 messages 中有条目,说明历史确实在数据库里。countDocuments 返回数量只用于确认非空,不要把它当成完整备份。若集合为空,先检查是不是连错数据库或连到了新初始化的 MongoDB;如果 MONGO_URI 指向外部实例,应去外部实例执行同样的查询。

备份数据卷后在新机器恢复并登录查看

备份前先停掉 LibreChat 和 MongoDB 容器,避免写入过程中复制出不一致的数据。若是绑定挂载,直接打包宿主机目录;若是命名卷,用临时容器把卷内容打包到当前目录。把压缩包复制到新机器后,在新机器创建同名卷或同路径目录,再解压回去,然后启动 compose。恢复后权限可能不对,MongoDB 容器常用非 root 用户运行,必要时按原环境调整目录属主。

docker compose stop librachat mongodb
# 绑定挂载目录
tar czf mongo-data.tgz -C /srv/librachat/data/mongodb .
# 命名卷
docker run `--rm` -v <卷名>:/data/db -v $(pwd):/backup alpine tar czf /backup/mongo-data.tgz -C /data/db .

新机器恢复顺序:先同步 compose 文件、.env 中与数据库和鉴权相关的配置,再恢复数据卷,最后启动服务。如果新机的 MONGO_URI 指向了另一个空库,恢复的卷不会被使用。

LibreChat 对话历史存在哪——换台机器部署还能接着聊吗?
docker run `--rm` -v <卷名>:/data/db -v $(pwd):/backup alpine sh -c 'cd /data/db && tar xzf /backup/mongo-data.tgz'
docker compose up -d

验证标准很直接:用旧账号登录新环境,侧栏能看到旧会话,打开其中一条能看到之前的消息。也可以再进 mongosh 用 db.messages.countDocuments({}) 确认数量非零。若页面空白但数据库有数据,检查 LibreChat 容器是否连到了恢复的 MongoDB,以及用户是否登录到了同一数据库中的账号。

确认用户级密钥的存放位置决定是否重填

迁移后消息发不出去,常见原因不是历史库没搬,而是用户级密钥或系统级密钥没接上。系统级模型密钥通常来自 .env 或容器环境变量,例如 OPENAI_API_KEY,这类值不会随 MongoDB 数据卷走,新环境必须重新填写。用户自己保存的模型密钥可能加密后存在 users 集合,加密依赖 CREDS_KEY、CREDS_IV 这类环境变量;如果新环境改了这两个值,数据库里的用户密钥即使还在也无法解密,表现就是界面有记录但调用模型报密钥错误。

迁移前先在旧环境确认这些配置的存放方式。下面的命令只用于本地核对,不要把带真实值的输出贴到公开聊天或工单里。

grep -E 'CREDS_KEY|CREDS_IV|JWT_SECRET|JWT_REFRESH_SECRET|MONGO_URI|OPENAI_API_KEY' .env

如果用户级密钥随数据库保存,应把数据库卷和 CREDS_KEY、CREDS_IV 一起迁移;如果模型密钥只来自环境变量,就在新环境重新设置。验证方式是登录后选一个可用模型发一条短消息,能正常返回说明密钥通道基本可用。若失败,先核对 CREDS_KEY、CREDS_IV 是否与旧环境一致,再检查新环境环境变量中的模型密钥是否有权限。不要把旧环境的完整 .env 直接暴露到公开仓库或问答区。