Discourse 数据迁移指南:从旧服务器到新服务器

UID:3 一级用户组

换服务器不丢数据、不停站,手把手教你完成论坛搬家

一、什么时候需要做迁移?

场景 说明
更换服务器 从A云厂商搬到B云厂商,或从低配升到高配
更换域名 论坛域名发生变化
灾备恢复 服务器故障后从备份恢复
自建转托管 从自托管迁移到 Discourse 官方托管

迁移前问自己三个问题

  1. 域名换不换?(换域名比换服务器复杂得多)

  2. 服务器架构变不变?(x64 ↔ ARM 可以,但需要测试)

  3. 能接受的停机时间是多少?(建议在凌晨进行)

二、迁移前的准备工作

2.1 环境一致性检查

必须保持一致

项目 检查方法 说明
Discourse 版本 /admin/upgrade 查看 新服务器必须安装相同版本
插件列表 对比 app.yml 中的 hooks 部分 插件不一致会导致恢复失败
PostgreSQL 版本 psql --version 必须主版本一致

可以在旧服务器上执行 git rev-parse HEAD 获取确切版本号

2.2 降低 DNS TTL(换域名/换IP时必做)

如果你计划换服务器 IP 或换域名,提前在 DNS 解析商处将 TTL(生存时间)降低到 300 秒(5分钟),这样可以减少切换时的停机时间 。

操作路径:域名管理后台 → 找到你的域名解析记录 → 将 TTL 改为 300

2.3 准备清单

项目 说明
目标服务器 已安装 Docker,2GB+ 内存,足够的硬盘空间
旧服务器备份 完整备份(含上传文件)或数据库备份 + 上传文件分离
维护窗口 通知用户,建议选择凌晨低峰期
回滚方案 旧服务器保持运行,直到新服务器验证通过

三、两种迁移方案

方案一:完整备份恢复(最简单,推荐90%场景)

这是官方推荐的方式,通过 Discourse 自带的备份/恢复功能完成迁移 。

架构图

flowchart TD     A[旧服务器] -->|创建完整备份| B[备份文件.tar.gz]     B -->|scp/rsync传输| C[新服务器]     C -->|恢复备份| D[新Discourse实例]     D -->|切换DNS| E[用户访问新服务器]     A -.->|保留回滚| F[旧服务器保持只读] 

第一步:在旧服务器上创建完整备份

登录旧服务器的 Discourse 后台:https://你的论坛域名/admin/backups

  1. 点击 Backup 按钮

  2. 确保勾选 Include uploads(包含上传文件)

  3. 点击 Start 开始备份

  4. 等待备份完成,下载或记录备份文件名

也可以通过命令行创建备份

bash

cd /var/discourse ./launcher enter app discourse backup exit 

备份文件会生成在 /var/discourse/shared/standalone/backups/default/ 目录下。

第二步:将备份文件传输到新服务器

bash

# 从旧服务器复制到新服务器 scp /path/to/backup.tar.gz root@新服务器IP:/var/discourse/shared/standalone/backups/default/ 

第三步:在新服务器上安装 Discourse

按照官方 Docker 安装流程,在新服务器上完成 Discourse 的基础安装,但不启动服务。

第四步:在新服务器上恢复备份

方法一:通过 Web 界面恢复

  1. 进入新服务器后台 /admin/backups

  2. 点击 Restore 标签页

  3. 找到上传的备份文件,点击 Restore

方法二:通过命令行恢复

bash

cd /var/discourse # 进入容器 ./launcher enter app # 开启恢复功能(如果提示权限不足) discourse enable_restore # 执行恢复 discourse restore /var/discourse/shared/standalone/backups/default/你的备份文件名.tar.gz # 退出容器 exit # 重建容器 ./launcher rebuild app 

恢复完成后会自动退出登录,用原管理员账号重新登录即可 。

方案二:分离备份(大容量附件场景)

如果你的论坛附件非常大(几十GB甚至上百GB),可以将附件和数据库分开处理,缩短迁移时间。

核心思路:

  • rsync 同步附件目录(支持断点续传)

  • 用数据库备份(.sql.gz)迁移核心数据

  • 最后用 uploads:migrate_to_s3 将附件迁移到对象存储(如 Cloudflare R2、阿里云OSS),彻底解决附件管理问题

这种方式适合附件超大、多次迁移的场景,也便于未来增量同步。

四、换域名时的特殊处理

如果你不仅要换服务器,还要换域名,比普通迁移多一步:

4.1 备份前修改配置

在旧服务器上修改 app.yml,将 DISCOURSE_HOSTNAME 改为新域名,然后重建一次:

bash

cd /var/discourse ./launcher rebuild app 

然后再创建备份。

4.2 恢复后检查

恢复完成后,登录新服务器后台,检查以下设置是否与新域名一致:

  • 站点设置中的 titlecontact_email

  • 通知邮件中的链接

  • 任何硬编码了旧域名的主题或插件

4.3 旧域名重定向(可选)

如果希望旧域名自动跳转到新域名,可以在旧服务器的 Nginx 配置中添加:

nginx

server {     listen 80;     server_name 旧域名.com;     return 301 https://新域名.com$request_uri; } 

五、对象存储迁移(可选但推荐)

如果你的附件很多,推荐在迁移的同时将附件迁移到对象存储(如 Cloudflare R2、阿里云OSS)。好处:

  • 永久解决附件容量问题:不占服务器硬盘

  • 减轻服务器 IO 压力:访问图片直接从 CDN 走

  • 未来迁移更简单:只需迁移数据库,附件不用动

5.1 在旧服务器上完成附件迁移

如果旧服务器的附件还在本地,可以在迁移前先将其全部上传到对象存储 :

bash

cd /var/discourse ./launcher enter app # 执行附件迁移命令 sudo -E -u discourse RAILS_ENV=production bundle exec rake uploads:migrate_to_s3 exit 

:warning: 注意:这个命令会移动附件到对象存储,原文件会被删除。执行前请确保配置正确。

5.2 检查附件是否全部迁移成功

bash

# 检查是否有帖子尚未映射到新的 S3 URL sudo -E -u discourse RAILS_ENV=production bundle exec rails r ' ids = Post.where("cooked LIKE '%/uploads/default/%'").pluck(:id) puts "还有 #{ids.count} 个帖子需要重新处理" if ids.any? ' 

如果还有帖子未映射,可以运行批量重新处理:

bash

sudo -E -u discourse RAILS_ENV=production bundle exec rake posts:rebake 

5.3 在新服务器配置中使用对象存储

编辑新服务器的 app.yml,添加对象存储相关环境变量 :

yaml

env:   DISCOURSE_USE_S3: "true"   DISCOURSE_S3_REGION: "auto"   DISCOURSE_S3_ENDPOINT: "https://你的账号ID.r2.cloudflarestorage.com"   DISCOURSE_S3_BUCKET: "discourse-uploads"   DISCOURSE_S3_ACCESS_KEY_ID: "你的Key"   DISCOURSE_S3_SECRET_ACCESS_KEY: "你的Secret"   DISCOURSE_S3_CDN_URL: "https://你的CDN域名"   DISCOURSE_BACKUP_LOCATION: "s3" 

重建新服务器即可直接使用对象存储中的附件。

六、常见问题与解决方法

Q1:恢复时报错 “备份文件不兼容”

原因:新服务器与旧服务器的 Discourse 版本或 PostgreSQL 版本不一致 。

解决

  1. 检查旧服务器的 Discourse 版本和插件列表

  2. 在新服务器上安装完全相同版本后再恢复

  3. 不要将较新的备份恢复到较旧的 Discourse 版本上

Q2:恢复后无法登录(HTTPS 问题)

原因:旧服务器开启了强制 HTTPS,但新服务器没有配置 SSL 证书 。

临时解决:通过 Rails 控制台暂时关闭强制 HTTPS:

bash

cd /var/discourse ./launcher enter app rails c SiteSetting.force_https = false exit exit 

然后配置好新服务器的 SSL 后再重新开启。

Q3:恢复后头像/图片不显示

原因:上传文件没有正确迁移,或者 CDN 地址配置错误。

解决

  • 检查备份是否勾选了 Include uploads

  • 检查 app.yml 中的 DISCOURSE_S3_CDN_URL 配置

  • 如果附件存储在本地,确认 /uploads 目录已正确同步

Q4:恢复后帖子中的链接还是旧域名

原因:帖子内容中写入了绝对链接。

解决

  • 如果是换域名,可以在恢复后批量替换

  • 通过 Rails 控制台或 SQL 执行替换(需谨慎操作,建议先备份)

七、企业级迁移流程(复杂场景)

如果你的论坛有以下特征:

  • 数据量巨大(百万级帖子)

  • 有复杂的权限模型(分类权限、私密板块)

  • 有定制插件和主题

  • 需要满足合规要求(审计、数据保留)

建议走企业级迁移流程,分为以下阶段 :

阶段 主要工作 产出
1. 发现与评估 分析源平台数据结构、统计数据量、梳理权限模型 迁移范围确认书
2. 环境搭建 创建迁移专用环境、部署相同版本 Discourse 迁移测试环境
3. 映射设计 分类->分类/标签映射、用户组映射、权限映射 数据映射文档
4. 多轮验证 导入测试数据、功能验证、用户验收测试 验收通过报告
5. 正式割接 源站只读、最终导出、导入生产环境、DNS切换 正式上线
6. 验证与清理 上线后验证、遗留链接重定向、旧站下线 迁移完成报告

典型时间线

  • 数据量 50 万帖以内:约 1-2 周

  • 数据量 50-200 万帖:约 3-6 周

  • 数据量 200 万帖以上:约 6-12 周

八、迁移后检查清单

恢复完成后,按以下清单逐项检查:

检查项 验证方法
管理员登录 用原账号登录新站点
用户数量 后台统计与旧站一致
帖子数量 后台统计 + 随机抽查
分类/标签 与旧站结构一致
附件/图片 打开几个帖子图片显示正常
私信 进入消息页面检查私信内容
搜索功能 搜索关键词能返回结果
邮件通知 注册新用户能否收到激活邮件
主题/样式 前台样式显示正常
插件功能 各插件工作正常

九、总结

你的情况 推荐方案 预计停机时间
换服务器、不换域名、附件少 完整备份恢复 5-15分钟
换服务器、附件大 分离备份(附件rsync + DB备份) 视附件大小而定
换服务器+换域名 换域名备份恢复 10-30分钟
同时想上对象存储 迁移前先做 uploads:migrate_to_s3 无额外停机
企业级复杂迁移 官方企业迁移服务 按项目定制

一句话:大多数场景用"完整备份恢复"就够了。如果你想顺便解决附件管理问题,迁移到对象存储是更一劳永逸的选择。

最新回复

请先登录后再回复 登录

uid:3 一级用户组
关注
发帖 25
评论 25
粉丝 0
关注 0
发新帖
目录
Discourse 数据迁移指南:从旧服务器到新服务器