こんにちは、Discourse コミュニティの皆様。
IPB 3.1 フォーラムを Discourse 2.1 にインポートした私の経験をお伝えします。これが皆様のお役に立てれば幸いです。
コミュニティの概要:
- トピック:Yii PHP フレームワーク(コード関連の議論とサポート)
- メンバー数:約 26,000 人
- トピック数:約 64,000
- ポスト数:約 293,000
このインポートは、16GB の RAM と 4 コアの CPU を搭載したマシンで 27 時間 46 分かかりました。
インポートの要件:
- メンバーは維持するが、すべてのスパムアカウントをクリーンアップする(約 25 万アカウントのうち、クリーンアップ後は約 2.6 万アカウントが残り)
- ウェブサイトから SSO を実装する(ユーザーアカウントは Discourse で管理されない)
- トピック、ポスト、カテゴリを元の URL のまま維持し、ウェブ検索結果や Stackoverflow などのプラットフォームからの他のリンクが引き続き機能するようにする
これは Migrating from Invision Power Board to Discourse - #23 by pfaffman に基づいています。インポーターの素晴らしい作業をしてくれた @pfaffman さんに感謝します。
準備
IPB からのデータエクスポート
mysqldump <databasename> > /tmp/ipb.sql
cd /var/www/yiiframework.com/forum/ && tar czvf uploads.tgz uploads/
SQL ダンプとアップロードファイルを新しいサーバーにコピーし、/var/discourse/shared/standalone/ に配置します。
ここでは Discourse のシンプルな Docker 設定を想定しています。
どのスクリプトを使用するか?
インポートスクリプトは ipboard.rb と ipboard3.rb の 2 つあります。ipboard3.rb は非常に荒削りで、また私たちが持っているテーブルスキーマにも適合しないため、ipboard.rb を採用しました。
現在の ipboard.rb インポートスクリプトは添付ファイルを適切に処理せず、コードタグの変換も行いません。私たちは PHP コードについて非常に多く話しているため、これは非常に重要です。そのため、スクリプトに以下の修正を加えました。
アップロードされた添付ファイルの利用可能化
インポートスクリプトは、ポストの添付ファイルをアップロードされたファイルへの URL に置き換えます。
IPB インスタンスを以前と同じ URL でオンラインのままにする場合、アップロードディレクトリへの URL を指定するだけで完了します(UPLOADS はインポートスクリプトの設定です、以下参照):
UPLOADS="https://www.yiiframework.com/forum/uploads"
しかし、古いフォーラムを完全に削除するために Discourse にインポートしているため、アップロードファイルを別の場所に配置する必要があります。Discourse の前に nginx プロキシ を使用している場合、サーバー上のディレクトリからアップロードされたファイルを配信するように設定できます。nginx 設定の server パーツに以下を追加してください:
location /ipb_uploads/ {
alias /var/www/ipb_uploads/;
}
そして、添付ファイルの URL を以下のように設定します(以下参照):
UPLOADS="https://forum.yiiframework.com/ipb_uploads"
Discourse コンテナでの MySQL のセットアップ
Discourse アプリコンテナで bash シェルを起動します:
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 クエリを作成しました:
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 のバージョンを表しています。設定にそのファイルが存在しない場合は、現在実行している postgres のバージョンに 10 を置き換えてください。
変更を読み込むために 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 書き換えルールを設定する必要があります。3 つのオプションがあります:
- Discourse の
permalink normalizations設定を使用して、URL から不要な部分を削除する - Discourse の前に nginx プロキシがある場合、nginx での書き換えルール
- 古いフォーラムが Discourse と異なる URL/ホストにあった場合、URL を書き換えるカスタムスクリプトを使用する(これが私が行ったことです)
以下が URL リダイレクトに使用する PHP コードです:
関連リソース
- Migrate a XenForo forum to Discourse
- Migrating from Invision Power Board to Discourse - #23 by pfaffman
- Feature: Invision Power Board Importer by pfaffman · Pull Request #5543 · discourse/discourse · GitHub
- SaltStack を使用した Discourse デプロイメント:
server-salt/states/discourse at master · yiisoft-contrib/server-salt · GitHub