# 将 IPB 3.1 论坛迁移到 Discourse

**URL:** <https://meta.discourse.org/t/migrate-an-ipb-3-1-forum-to-discourse/96609>\
**Category:** Sysadmins\
**Tags:** how-to\
**Created:** [2018 年9 月 7 日 09:17 UTC](https://meta.discourse.org/t/migrate-an-ipb-3-1-forum-to-discourse/96609 "2018-09-07T09:17:09Z")\
**Posts on this page:** 1\
**Showing post:** 1

<div class="post-metadata">

作者： ![cebe](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/cebe/32/119560_2.png) [@cebe](https://meta.discourse.org/u/cebe)\
发布日期： [2018 年9 月 7 日 09:17 UTC](https://meta.discourse.org/t/migrate-an-ipb-3-1-forum-to-discourse/96609/1 "2018-09-07T09:17:09Z")

</div>

大家好，Discourse 社区，

我想分享我将 IPB 3.1 论坛导入 Discourse 2.1 的经验，希望这对其他人有所帮助。

社区简介：

- 主题：Yii PHP 框架（代码相关讨论和支持）
- 成员：约 2.6 万
- 话题：约 6.4 万
- 帖子：约 29.3 万

在一台拥有 16GB RAM 和 4 个 CPU 核心的机器上，导入过程耗时 27 小时 46 分钟。

导入要求：

- 保留成员，但清理所有垃圾账户（约 25 万个账户，清理后保留约 2.6 万个）
- 从网站实施 [SSO](https://meta.discourse.org/t/official-single-sign-on-for-discourse-sso/13045)（用户账户不由 Discourse 管理）
- 保留话题、帖子和分类及其原始 URL，以便网络搜索结果仍然有效，并且来自 Stackoverflow 等平台的链接也能正常工作

这是基于 [Migrating from Invision Power Board to Discourse - #23 by pfaffman](https://meta.discourse.org/t/migrating-from-invision-power-board-to-discourse/34639/23) 的，感谢 @pfaffman 在导入器方面所做的出色工作。

# 准备工作

## 从 IPB 导出数据

```
mysqldump <数据库名> > /tmp/ipb.sql
cd /var/www/yiiframework.com/forum/ && tar czvf uploads.tgz uploads/

```

将 SQL 转储文件和上传文件复制到新服务器，并将它们放入 `/var/discourse/shared/standalone/`。  
这里假设使用的是 Discourse 的简单 Docker 设置。

## 使用哪个脚本？

有两个导入脚本：[ipboard.rb](https://github.com/discourse/discourse/blob/v2.1.0.beta6/script/import_scripts/ipboard.rb) 和 [ipboard3.rb](https://github.com/discourse/discourse/blob/v2.1.0.beta6/script/import_scripts/ipboard3.rb)。`ipboard3.rb` 脚本看起来非常粗糙，也不符合我们的表结构，所以我选择了 `ipboard.rb`。

当前版本的 `ipboard.rb` 导入脚本对附件处理不佳，也没有转换代码标签，而这对我们非常重要，因为我们经常讨论 PHP 代码。因此，我对脚本进行了以下修改：

> <https://github.com/discourse/discourse/pull/6371>
>
> \- improve handling of code tags (current version made these unreadable)
> \- add a… converion for lists, these were not converted to markdown before
> \- improved handling of uploaded attachments:
> - show images directly and add a link to them
> - for non-images just provide a download link

## 使上传的附件可用

导入脚本会将帖子附件替换为上传文件的 URL。  
如果您打算在原有 URL 上保持 IPB 实例在线，只需指定上传目录的 URL（UPLOADS 是导入脚本的配置，见下文）即可完成：

```
UPLOADS="https://www.yiiframework.com/forum/uploads"

```

但我们导入 Discourse 是为了完全移除旧论坛，因此必须将上传文件放到其他地方。如果您在 Discourse 前面使用了 [nginx 代理](https://meta.discourse.org/t/adding-an-offline-page-when-rebuilding/45238)，可以配置它从服务器上的某个目录提供上传文件。将以下内容放入 nginx 配置的 `server` 部分：

```
location /ipb_uploads/ {
    alias /var/www/ipb_uploads/;
}

```

并按如下方式配置附件 URL（见下文）：

```
UPLOADS="https://forum.yiiframework.com/ipb_uploads"

```

## 在 Discourse 容器中设置 MySQL

在 Discourse 应用容器中启动一个 bash shell：

```
docker exec -it app bash

```

在容器中安装 MySQL 并导入数据库：

```
apt-get install mysql-server mysql-client libmysqlclient-dev
service mysql start
echo "create database ipb" | mysql -uroot -p
mysql -uroot -p ipb < /shared/ipb.sql

```

当我第一次尝试导入以测试脚本时，导入 20 万个用户花了数天时间，其中我们知道有大量是垃圾账户，因此我们创建了一些 SQL 查询来删除从未发布过任何内容的账户：

> <https://gist.github.com/samdark/c65c22b4a63d565917360ef4b1f1d5c7>

请注意，我们将使用 SSO，因此删除的用户在登录时会被重新创建。  
如果您不使用 SSO，删除用户的标准可能会有所不同。  
您可以直接导入数据而不清理。

```
mysql -uroot -p
# 然后应用清理查询

```

接下来，我们需要为导入脚本安装依赖项：

```
cd /var/www/discourse
echo "gem 'mysql2'" >> Gemfile
echo "gem 'reverse_markdown'" >> Gemfile
bundle install --no-deployment

```

要允许数据库访问 Discourse 的 Postgres 数据库，请将 `/etc/postgresql/10/main/pg_hba.conf` 中的 `peer` 替换为 `trust`。注意，10 代表 Postgres 版本，如果您的设置中该文件不存在，请将 10 替换为您当前运行的 Postgres 版本。  
重启 Postgres 以加载更改：`service postgresql restart`

# 导入

准备头像和上传文件：

```
mkdir /shared/imports
mv /shared/uploads.tgz /shared/imports
cd /shared/imports && tar xzvf uploads.tgz

```

运行导入器脚本：

```
cd /var/www/discourse
DB_HOST="localhost" DB_NAME="yiisite" DB_USER="root" DB_PW="root" TABLE_PREFIX="ipb_" IMPORT_AFTER="1970-01-01" UPLOADS="https://www.forum.yiiframework.com/ipb_uploads" AVATARS_DIR="/shared/imports/uploads/" USERDIR="user" bundle exec ruby script/import_scripts/ipboard.rb | tee import.log

```

请务必根据上述讨论调整 UPLOADS URL，因为上传文件将作为链接包含在帖子中，指向原始上传文件。

# 清理

如果一切顺利，使用 `service mysql stop`、`apt-get purge mysql-server`、`rm -rf /var/lib/mysql` 进行清理。

# 设置 URL 重定向

为了保持现有论坛 URL 的完整性，导入脚本为每个话题创建了反映 IPB 中话题和分类 URL 的永久链接。  
然而，这些永久链接并不涵盖话题中特定帖子的链接或不同页面的链接。  
为了使这些 URL 正常工作，您需要配置一些 URL 重写规则，有以下三种选择：

- 使用 Discourse 中的 `permalink normalizations` 设置删除 URL 中不必要的部分
- 在 nginx 中配置重写规则，如果您在 Discourse 前面使用了 nginx 代理
- 如果旧论坛位于与 Discourse 不同的 URL/主机上，您可以编写自定义脚本来重写 URL（这就是我所做的）

这是我们用于 URL 重定向的 PHP 代码：

> <https://github.com/yiisoft-contrib/yiiframework.com/blob/94653588e99ff718b3a356e344f359c6c799f4ff/controllers/SiteController.php#L98-L169>

> <https://github.com/yiisoft-contrib/yiiframework.com/blob/94653588e99ff718b3a356e344f359c6c799f4ff/config/urls.php#L108-L110>

# 相关资源

- [Migrate a XenForo forum to Discourse](https://meta.discourse.org/t/importing-xenforo-to-discourse/45232)
- [Migrating from Invision Power Board to Discourse - #23 by pfaffman](https://meta.discourse.org/t/migrating-from-invision-power-board-to-discourse/34639/23)
- [Feature: Invision Power Board Importer by pfaffman · Pull Request #5543 · discourse/discourse · GitHub](https://github.com/discourse/discourse/pull/5543)
- 使用 [SaltStack](https://saltstack.com/salt-open-source/) 进行 Discourse 部署：  
[server-salt/states/discourse at master · yiisoft-contrib/server-salt · GitHub](https://github.com/yiisoft-contrib/server-salt/tree/master/states/discourse)

---

_[View the full topic](https://meta.discourse.org/t/migrate-an-ipb-3-1-forum-to-discourse/96609)._
