v12 将底层数据库从 MongoDB 更换为 PostgreSQL。你的文章、评论、配置等所有数据都会保留,但需要执行一次迁移操作。
数据迁移工具已独立为 npm 包
@mx-space/mongo-pg-cli。 v12 镜像不再内置migrate-mongo-to-postgres.ts脚本,也不再内置mongodump/mongo-tools。所有迁移命令都通过npx @mx-space/mongo-pg-cli@latest执行(要求宿主机或临时容器有 Node.js 22+)。
- 数据库:MongoDB → PostgreSQL(性能更好,数据更安全)
- 备份方式:
mongodump→pg_dump(以后备份用新命令) - 环境变量:
DB_HOST/MONGO_CONNECTION等旧变量失效,改用PG_URL等 - 镜像内容:v12 镜像不再附带
mongodump与旧迁移脚本;备份与迁移须在宿主机或一次性容器中完成
- 前端页面、API 接口和之前完全一致
- 你的文章、评论、图片、配置全部保留
- 登录方式、密码、API Key 不受影响
| 你的部署方式 | 操作复杂度 | 预计停站时间 |
|---|---|---|
| Docker(多数用户) | 中等 | 5–30 分钟 |
| 源码/PM2 部署 | 较高 | 10–60 分钟 |
⚠️ 升级前务必备份。迁移工具是只读且幂等的,但备份是最后一道保险。
开始前,确认以下事项:
- 当前版本是 v11.x(v10 或更早请先升到 v11)
- 已备份 MongoDB 数据(见下方命令)
- 服务器或临时容器有 Node.js 22+(用于跑
npx) - 服务器剩余磁盘空间 > 当前数据量的 2 倍
- 已准备好至少 30 分钟的维护窗口(期间不要发文章/评论)
无论你用哪种方式部署,先在 MongoDB 仍在运行的状态下执行备份。注意 v12 的 docker-compose 已不含 mongo 容器,本步要在仍是 v11 的 mongo 容器上做。
# 进入你放 docker-compose.yml 的文件夹,或者 core 源码文件夹
cd ~/mx-space/core
# 方式 A:现存 v11 mongo 容器中已自带 mongodump
docker exec -i $(docker ps -q -f name=mongo) mongodump --archive > backup-mongo-$(date +%Y%m%d).archive
# 方式 B:宿主机有 mongodump
mongodump --uri="mongodb://localhost:27017/mx-space" --archive=backup-mongo-$(date +%Y%m%d).archive --gzip
# 方式 C:什么都没有,临时容器
docker run --rm --network host mongo:7 \
mongodump --uri="mongodb://127.0.0.1:27017/mx-space" --archive --gzip > backup-mongo-$(date +%Y%m%d).archive.gz
# 同时打包整个数据目录
tar czvf mx-space-full-backup-$(date +%Y%m%d).tar.gz ./data验证备份:确认 archive 文件大小不为 0,且 .tar.gz 包含 data/mx-space 目录。
无论部署方式,迁移命令都是同一个:
# dry-run(默认):只读 mongo,模拟迁移,不写 PG
npx @mx-space/mongo-pg-cli@latest --mode dry-run
# apply:真正写入 PG,幂等可重跑
npx @mx-space/mongo-pg-cli@latest --mode apply| 变量 | 默认 | 说明 |
|---|---|---|
MONGO_URI |
mongodb://127.0.0.1:27017/mx-space |
源 v11 MongoDB URI |
PG_URL |
由 PG_HOST/PG_PORT/... 拼接 |
目标 PostgreSQL URI |
SNOWFLAKE_WORKER_ID |
900 |
迁移产生的行的 worker id,建议保留 900–999 给迁移用 |
完整参数与故障排查见 @mx-space/mongo-pg-cli README。
关键:只停
app服务,不要docker compose down。MongoDB 容器需要继续运行,CLI 会从中读取数据。
cd ~/mx-space/core
docker compose stop app确认 mongo 仍在运行并对宿主机暴露 27017:
docker ps | grep mongo
docker port $(docker ps -q -f name=mongo) | grep 27017
# 期望看到 27017/tcp -> 0.0.0.0:27017# 备份旧配置
cp docker-compose.yml docker-compose.yml.v11.backup
# 拉取新的 docker-compose.yml(已内置 PostgreSQL)
wget -O docker-compose.yml https://fastly.jsdelivr.net/gh/mx-space/core@master/docker-compose.yml# 只启动数据库,先不启动主服务
docker compose up -d postgres redis等待 10 秒,确认 PostgreSQL 健康,并暴露 5432:
docker compose ps
docker port postgres | grep 5432
# 期望看到 postgres 状态为 healthy,端口 5432/tcp -> 0.0.0.0:5432宿主机有 Node.js 22+ 时,最简单:
MONGO_URI="mongodb://127.0.0.1:27017/mx-space" \
PG_URL="postgres://mx:mx@127.0.0.1:5432/mx_core" \
npx @mx-space/mongo-pg-cli@latest --mode dry-run
# 报告无致命错误后再 apply
MONGO_URI="mongodb://127.0.0.1:27017/mx-space" \
PG_URL="postgres://mx:mx@127.0.0.1:5432/mx_core" \
npx @mx-space/mongo-pg-cli@latest --mode apply宿主机没有 Node.js(仅 Linux,--network host 才支持本机端口):
docker run --rm --network host \
-e MONGO_URI="mongodb://127.0.0.1:27017/mx-space" \
-e PG_URL="postgres://mx:mx@127.0.0.1:5432/mx_core" \
node:22-alpine \
npx -y @mx-space/mongo-pg-cli@latest --mode apply如果 --network host 不可用(macOS / Windows Docker Desktop),可改为加入 v12 compose 网络,并先把旧 mongo 容器接入:
docker network connect mx-space_mx-space mongo
docker run --rm --network mx-space_mx-space \
-e MONGO_URI="mongodb://mongo:27017/mx-space" \
-e PG_URL="postgres://mx:mx@postgres:5432/mx_core" \
node:22-alpine \
npx -y @mx-space/mongo-pg-cli@latest --mode apply预期输出:
Rows allocated: XXXX与你的文章/评论数量接近Missing refs: 0(少量孤儿数据可接受)- 最后出现
✅ Migration finished without missing references.
如果报错:
| 错误 | 原因 | 解决 |
|---|---|---|
MongoServerSelectionError |
mongo 端口未暴露 / 网络未联通 | 检查 mongo 容器是否映射 27017,或确认 --network 设置正确 |
connection refused(PG) |
PG 还没启动好 | 等 30 秒重试 |
Missing refs > 0 |
有孤儿数据 | 通常可忽略,截图记录后继续 |
| 其他错误 | 未知问题 | 不要继续,保留日志,回滚到 v11 |
docker compose up -d逐项检查:
- 打开首页,文章列表正常显示
- 打开一篇文章,内容和评论都在
- 登录后台(
你的域名/proxy/qaqdmin),能正常登录 - 后台「其他 - 备份」页面能正常打开
- 发一篇测试文章,能正常发布和显示
- 删除测试文章,正常删除
全部通过 = 升级成功。
cd ~/mx-space/core/apps/core
pm2 stop ecosystem.config.jscd ~/mx-space/core
git fetch origin
git checkout v12.x.x # 或 master 上的最新 v12 tag
pnpm i如果你还没有 PostgreSQL 16+:
# Ubuntu/Debian
sudo apt install postgresql-16
# macOS
brew install postgresql@16
brew services start postgresql@16
# 创建数据库和用户
sudo -u postgres psql -c "CREATE USER mx WITH PASSWORD 'mx';"
sudo -u postgres psql -c "CREATE DATABASE mx_core OWNER mx;"编辑 apps/core/.env 或 ecosystem.config.js,删除旧变量:
- DB_HOST=xxx
- MONGO_CONNECTION=xxx添加新变量:
# 最简单的方式:直接用连接字符串
PG_URL=postgresql://mx:mx@localhost:5432/mx_core
# 或者分开写
PG_HOST=localhost
PG_PORT=5432
PG_USER=mx
PG_PASSWORD=mx
PG_DATABASE=mx_core
# 必须添加:工作节点 ID,单实例填 1
SNOWFLAKE_WORKER_ID=1# 先试运行(不写入,只检查)
SNOWFLAKE_WORKER_ID=900 \
MONGO_URI="mongodb://localhost:27017/mx-space" \
PG_URL="postgresql://mx:mx@localhost:5432/mx_core" \
npx @mx-space/mongo-pg-cli@latest --mode dry-run
# 确认无报错后,正式迁移
SNOWFLAKE_WORKER_ID=900 \
MONGO_URI="mongodb://localhost:27017/mx-space" \
PG_URL="postgresql://mx:mx@localhost:5432/mx_core" \
npx @mx-space/mongo-pg-cli@latest --mode apply迁移阶段建议把
SNOWFLAKE_WORKER_ID设为900–999,与运行时实例的 worker id 错开,详见 CLI README。
pnpm build
pnpm bundle
cd apps/core
pm2 start ecosystem.config.js同 Docker 验证清单(见 A6)。
确认 v12 运行稳定后:
# Docker 用户:删除旧 MongoDB 容器和数据卷
docker compose rm -f mongo
docker volume rm mx-space_mongo_data # 名字可能不同,用 docker volume ls 查看
# 源码用户:停止并卸载 MongoDB
sudo systemctl stop mongod
# (保留备份文件,卸载与否自行决定)什么都不用丢,直接回到 v11:
# Docker
cd ~/mx-space/core
cp docker-compose.yml.v11.backup docker-compose.yml
docker compose up -d
# 源码
cd ~/mx-space/core
git checkout v11.x.x
pm2 restart ecosystem.config.js立即切回 v11:
# 停止 v12
docker compose down # 或 pm2 stop ecosystem.config.js
# 恢复 v11 配置和代码
cp docker-compose.yml.v11.backup docker-compose.yml # Docker
git checkout v11.x.x # 源码
# 启动 v11(仍然连 MongoDB)
docker compose up -d # 或 pm2 start ecosystem.config.jsMongoDB 数据在迁移过程中只读不会被修改,所以回滚后数据完全和升级前一样。
这种情况比较复杂,因为新数据在 PostgreSQL 里,回滚到 MongoDB 会丢失这部分。建议:
- 先导出 v12 新增的内容(手动复制文章等)
- 或者直接在 v12 上排查修复问题(推荐)
- 如需帮助,带上日志发 GitHub Issue
不会。迁移是只读 MongoDB 写入 PostgreSQL,MongoDB 原数据不动。这也是为什么回滚到 v11 是安全的。
不会。图片、附件存在文件系统(data/mx-space)或对象存储里,不在数据库中,完全不受影响。
可以。CLI 持久化 mongo_id_map,重复执行 apply 不会重复导入已迁移的数据。
v12 之后,迁移工具独立成 @mx-space/mongo-pg-cli 单独发布,与运行时镜像解耦。这样:
- 镜像更小,启动更快
- 迁移工具可以独立迭代修复,无需重发镜像
- 一次性的迁移工具不应作为运行时依赖常驻
PostgreSQL 是更成熟的关系型数据库,能更好地保证数据完整性,未来的功能扩展(如更复杂的查询、统计分析)也会更容易。对普通用户而言,日常体验不会有明显变化,但长期更稳定。
一般不需要。如果你用的是 Shiro / Kami / Yohaku 等官方主题,直接兼容。只有直接调用 API 的第三方工具可能需要更新 @mx-space/api-client 到 v12 版本。
@mx-space/mongo-pg-cliREADME(CLI 完整参数与故障排查)- 生产环境迁移详细手册(运维/技术人员参考)
- v11 升级指南
- GitHub Issues