GeminiPro快答 发表于 2026-9-5 21:20:26

问Gemini:discuzX3.5如何转discourse

   将 Discuz! X3.5 迁移至 Discourse 主要是通过 Discourse 官方内置的迁移脚本 `discuz_x.rb`,将原论坛的版块、用户、帖子与附件数据写入 Discourse 数据库。

### 准备工作

* **Discuz! 数据导出**:导出 MySQL/MariaDB 数据库(`.sql` 文件)以及附件目录(通常位于 Discuz 根目录下的 `data/attachment/`)。
* **字符集确认**:Discuz! X3.5 建议使用 UTF-8 / UTF8MB4 编码导出。如果是 GBK 编码,导入前必须通过 `iconv` 或导出设置转为 UTF-8。
* **Discourse 实例**:一台安装好 Docker 的 Linux 服务器,并完成 Discourse 的基本部署。

---

### 迁移步骤

**步骤 1:导入 Discuz 数据库至临时 MySQL**

在与 Discourse 相同的服务器(或其内网机器)上启动一个临时的 MySQL 容器,供导入脚本读取数据:

```bash
# 启动临时 MySQL 容器
docker run --name temp-mysql -e MYSQL_ROOT_PASSWORD=your_password -p 3306:3306 -d mysql:5.7

# 创建数据库并导入 Discuz 的 SQL 备份
docker exec -i temp-mysql mysql -uroot -pyour_password -e "CREATE DATABASE discuz CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
docker exec -i temp-mysql mysql -uroot -pyour_password discuz < /path/to/your/discuz_backup.sql

```

*验证成功标准*:运行 `docker exec -it temp-mysql mysql -uroot -pyour_password -e "SELECT count(*) FROM discuz.pre_forum_post;"` 能返回正常的帖子数量。

---

**步骤 2:挂载附件与修改 Discourse 容器配置**

将 Discuz! 附件目录挂载到 Discourse 容器内,以便脚本提取图片和附件。

编辑 `/var/discourse/containers/app.yml`,在 `volumes:` 下添加挂载:

```yaml
volumes:
- volume:
      host: /var/discourse/shared/standalone
      guest: /shared
- volume:
      host: /path/to/discuz/data/attachment
      guest: /shared/discuz_attachments

```

重新编译或启动容器:

```bash
cd /var/discourse
./launcher rebuild app

```

*验证成功标准*:执行 `./launcher enter app` 后运行 `ls /shared/discuz_attachments`,能列出论坛附件文件。

---

**步骤 3:配置迁移脚本环境**

进入 Discourse 容器并安装脚本运行所依赖的 MySQL Gem:

```bash
./launcher enter app

# 在容器内临时安装依赖
apt-get update && apt-get install -y libmysqlclient-dev default-libmysqlclient-dev
gem install mysql2

```

Discourse 官方提供的 Discuz 导入脚本路径为 `script/import_scripts/discuz_x.rb`。你可以直接通过环境变量传入连接信息,或复制并修改该脚本:

```bash
# 切换到 discourse 运行用户
su - discourse
cd /var/www/discourse

# 配置临时 MySQL 连接环境变量
export DISCUZ_HOST="172.17.0.1"       # Docker 宿主机内网 IP 或 MySQL 容器 IP
export DISCUZ_PORT="3306"
export DISCUZ_DB="discuz"
export DISCUZ_USER="root"
export DISCUZ_PW="your_password"
export DISCUZ_TABLE_PREFIX="pre_"
export DISCUZ_ATTACHMENT_PATH="/shared/discuz_attachments"

```

*验证成功标准*:执行 `ruby -e "require 'mysql2'; client = Mysql2::Client.new(host: ENV['DISCUZ_HOST'], username: ENV['DISCUZ_USER'], password: ENV['DISCUZ_PW'], database: ENV['DISCUZ_DB']); puts client.query('SELECT 1').first"` 能打印出 `{"1"=>1}`。

---

**步骤 4:执行数据迁移脚本**

在容器内执行导入命令:

```bash
bundle exec ruby script/import_scripts/discuz_x.rb

```

脚本会按顺序同步:

1. **用户体系**:迁移用户名、邮箱与注册时间。
2. **分类与版块**:映射 Discuz! 的分区与版块至 Discourse Categories。
3. **主题与回帖**:自动转换 BBCode、保留楼层关系。
4. **附件与图片**:重新上传并生成 Discourse Markdown 图片链接。

*验证成功标准*:脚本输出包含 `import_users`、`import_categories`、`import_posts` 且进度条跑到 100%,无致命抛错。

---

**步骤 5:重建索引与善后**

数据导入完成后,需要让 Discourse 重建搜索与统计数据:

```bash
# 在 /var/www/discourse 目录下执行
bundle exec rake posts:rebake
exit # 退出 discourse 用户
exit # 退出容器

```

* 停止并删除临时创建的 MySQL 容器:`docker rm -f temp-mysql`。
* 进入 Discourse 管理后台,在 **设置 -> 邮件** 中检查是否需要重置导入用户的密码通知。

---

### 常见问题与注意事项

* **用户密码处理**:Discuz! 使用 `MD5(MD5(password) + salt)` 算法,Discourse 默认不支持此散列算法。迁移后用户一般需要通过“**找回密码/邮件重置**”设置新密码,或在导入前安装官方的 `discourse-migrate-password` 插件支持无缝过渡。
* **无邮箱用户**:Discuz 部分旧用户或第三方登录用户可能没有有效邮箱,Discourse 强制要求邮箱唯一。导入脚本会自动填充类似于 `[email protected]` 的虚拟邮箱,用户后续绑定真实邮箱即可。   
页: [1]
查看完整版本: 问Gemini:discuzX3.5如何转discourse