bbPress WordPress プラグインのフォーラムを Discourse へ移行する

最近、Discourse に内蔵されているマイグレーションスクリプトを使用して、bbPress のデータベースマイグレーションに成功しました。そこで、その手順をステップバイステップのチュートリアルとして共有します。

注意: このチュートリアルは、bbPress プラグイン(レガシーなスタンドアロン版 bbPress ではありません)向けです。

どのデータをインポートできますか?

  • ユーザー(匿名ユーザーを含む)
  • カテゴリ
  • トピック
  • 投稿
  • プライベートメッセージ(BuddyPress を経由)
  • アタッチメント
  • パーマリンク

マイグレーションを開始する前に、マシン(または仮想マシン内)に開発環境を設定し、Docker コンテナ内ではなく、そこでインポートを実行してください。Docker コンテナ内で試したところ、peer authentication failed というエラーが発生しました。そのため、開発用マシンを使用することを強くお勧めします。開発環境のインストールについては、macOS または Ubuntu / Debian のインストールガイドをご覧ください。

Discourse には Ruby 3.4 以上が必要です。Ruby のバージョンは以下のコマンドで確認できます。

ruby -v

次に、mysql2 gem を使用できるようにするため、libmysqlclient-dev 依存関係をインストールする必要があります。

sudo apt-get install libmysqlclient-dev

インストールが正常に完了したら、Discourse の開発環境のインストールパス(通常は ~/discourse)に移動します。

cd ~/discourse

データベース接続の設定

bbPress のインポートスクリプトは、すべてのデータベース接続設定を環境変数から読み取ります。スクリプトファイルを編集する必要はありません。以下の環境変数がサポートされています。

変数 デフォルト 説明
BBPRESS_HOST localhost MySQL データベースホスト
BBPRESS_USER root MySQL ユーザー名
BBPRESS_PW (空) MySQL パスワード
BBPRESS_DB bbpress MySQL データベース名
BBPRESS_PREFIX wp_ WordPress テーブルプレフィックス
BBPRESS_ATTACHMENTS_DIR /path/to/attachments bbPress のアタッチメントディレクトリへのパス

ローカルホストからデータベースをマイグレーションする場合、通常はデータベース名を設定するだけで十分です。

IMPORT=1 bundle && IMPORT=1 BBPRESS_DB="my_bbpress" bundle exec ruby script/import_scripts/bbpress.rb

外部サーバーからデータベースをマイグレーションする場合、ホスト、ユーザー名、パスワードも設定する必要があります。

IMPORT=1 bundle && IMPORT=1 BBPRESS_HOST="REMOTE_HOST_NAME" BBPRESS_USER="DB_USERNAME" BBPRESS_PW="MY_SECURE_PASSWORD" BBPRESS_DB="DB_NAME" bundle exec ruby script/import_scripts/bbpress.rb

おめでとうございます! bbPress から Discourse へのデータベースマイグレーションが正常に完了しました :clap: :wave: :boom:

次に、管理画面 /admin/backups からバックアップを取得し、ライブの Discourse ウェブサイトにインポートしてください。


bbPress フォーラムを Discourse へ移行した後、WordPress ウェブサイトをメインサイトとして引き続き使用し、Discourse と連携させたい場合は、Discourse の公式 WordPress プラグイン をインストールしてください。

「いいね!」 15

Just wanted to thank you for providing this step-by-step guide. We migrated our site from bbpress to Discourse with minimal headache thanks to you. Since we’re running multisite wordpress there were a few tweaks to make to the importer, but other than that it went very smoothly. Thanks!

「いいね!」 3

If you can share your tweaks then it will be helpful to other multisite owners.

「いいね!」 1

Admittedly I didn’t take very good notes, and have since killed the VM it
was on (sorry!) but the basic gist is that if your bbpress install is not
on the primary site of the Multisite setup you’ll need to a) set the
environmental variable for BBPRESS_PREFIX to include your site’s ID number
(e.g. wp_6_ ) and then edit the migration script to use wp_users rather
than #{BBPRESS_PREFIX} for the Users sql. This is because on Multisite
installations the wp_users table is shared across sites and then each site
has its own tables for posts, postmeta, etc.

「いいね!」 5

thanks for the details :thumbsup:

I recently posted on how to import bbpress into discourse

「いいね!」 2

Great job on the tutorial! But it’s confusing to have two different guides on this. Do they serve different purposes? Otherwise we should figure out how to merge them.

That guide is about how to import bbpress inside of a development environment, mine is how to import bbpress using the docker container. It’s just 2 different ways to go. I’d recommend importing via docker container since it doesn’t ask for the additional step of setting up a development environment, which can be cumbersome.

Hello I am stuck trying to import successfully after all users are done importing.

As soon it begins to import anonymous users it cancels with an error of “Invalid Email… and Validation failed: Username can’t be blank (ActiveRecord::RecordInvalid)”.

I added the error below, does anyone encountered this before or have any ideas on what I should do?

Thanks,

importing anonymous users...
Invalid email '' for ''. Using '6be92499a6f885cb271d94bffd5e667b@email.invalid'
Error on record: {:id=>"", :email=>"", :name=>"", :website=>nil}
Traceback (most recent call last):
	23: from script/import_scripts/bbpress.rb:512:in `<main>'
	22: from /home/lutechi/discourse/script/import_scripts/base.rb:49:in `perform'
	21: from script/import_scripts/bbpress.rb:31:in `execute'
	20: from script/import_scripts/bbpress.rb:153:in `import_anonymous_users'
	19: from /home/lutechi/discourse/script/import_scripts/base.rb:249:in `create_users'
	18: from /home/lutechi/discourse/script/import_scripts/base.rb:249:in `each'
	17: from /home/lutechi/discourse/script/import_scripts/base.rb:261:in `block in create_users'
	16: from /home/lutechi/discourse/script/import_scripts/base.rb:337:in `create_user'
	15: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/transactions.rb:212:in `transaction'
	14: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/database_statements.rb:267:in `transaction'
	13: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/transaction.rb:236:in `within_new_transaction'
	12: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/2.6.0/monitor.rb:230:in `mon_synchronize'
	11: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/transaction.rb:239:in `block in within_new_transaction'
	10: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/database_statements.rb:267:in `block in transaction'
	 9: from /home/lutechi/discourse/script/import_scripts/base.rb:338:in `block in create_user'
	 8: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/suppressor.rb:48:in `save!'
	 7: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/transactions.rb:315:in `save!'
	 6: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/transactions.rb:385:in `with_transaction_returning_status'
	 5: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/transactions.rb:212:in `transaction'
	 4: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/database_statements.rb:265:in `transaction'
	 3: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/transactions.rb:387:in `block in with_transaction_returning_status'
	 2: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/transactions.rb:315:in `block in save!'
	 1: from /home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/validations.rb:52:in `save!'
/home/lutechi/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/validations.rb:80:in `raise_validation_error': Validation failed: Username can't be blank (ActiveRecord::RecordInvalid)

この役立つチュートリアルをありがとうございます。私の環境でも動作しましたが、いくつかの小さな問題があります:

  1. インストールプロセスで PostgreSQL 11 がインストールされたようですが、Discourse のホスト版は PostgreSQL 10 に対応しているため、少し混乱を招いています。

  2. インポートしたユーザーが WordPress の認証情報で Discourse にログインできないようです。自分のユーザーアカウントで試しましたが、ユーザー名でもメールアドレスでもどちらも機能しません。WordPress 側では問題なくログインでき、Discourse にもユーザーアカウントが存在し、関連するフォーラムスレッドも確認できます。パスワードや認証に関する変更があったのでしょうか?

WordPress から SSO を使用していますか?

これには migrate password プラグイン が必要です。インストールされましたか?

「いいね!」 3

こんにちは、マイケルさん。

いいえ、そのプラグインについての言及は初めて見つけたので、指摘してくださりありがとうございます。もしかしたら何か手順を見落としているかもしれませんね!共有してくださり、ありがとうございます。明日、目が少し休まったら詳しく見てみますね。

ルース

「いいね!」 3

こんにちは :waving_hand:

ユーザーがアップロードした画像も移行可能ですか?
ユーザーアップロード用のプラグインは GD bbPress Attachments です。

では、乾杯 :beers:

スクリプトは添付ファイルのインポートを行っているようです。

添付ファイルのパスを指定した BB_PRESS_ATTACHMENTS_DIR 環境変数を設定する必要があります。

「いいね!」 1

bbPress プラグインのアップロードは、WordPress インストールの /uploads フォルダに保存されているようです。これには GD bbPress Attachments が使用されていました。BB_PRESS_ATTACHMENTS_DIR 変数にどのようなパスを設定すべきか確信が持てません。少しお手伝いいただけますか?アップロードへの完全な URL パス(例:http://www.example.com/httpdocs/wp-content/uploads/2018/02/picture.png)を指定すべきでしょうか、それとも他に何かあるのでしょうか?

インポートスクリプトが正常に完了しなかったことがわかりました。import_private_messages ステップが失敗したためです。フォーラムではプライベートメッセージが有効になっていませんでした。そのステップをスクリプトから削除しましたが、table wp_bb_attachments doesn't exist というメッセージで失敗します。これは事実です。しかし、データベースには添付ファイルに関連するテーブルが見つかりません。では、当初どのようにして添付ファイルが機能していたのでしょうか?:thinking:

添付ファイルは、インポートを実行するサーバー上のディレクトリに配置する必要があります。

スクリプトが探している添付ファイルのテーブルが表示されない場合は、スクリプトが想定している方法とは異なる方法で添付ファイルを処理している可能性があります。私の推測では、それらはまだ見つけていない別のテーブルにあるか、または相対ファイル名が投稿自体に含まれているかのどちらかだと思われます。

それらをインポートするための別の関数が必要なのではないでしょうか。予算があるようでしたらお手伝いできます。Redirecting… にはインポートに関する情報が掲載されています。完全なサービスは不要と思われるので、そこに記載されている料金を下回る費用で済むはずです。

Discourse は常に Docker コンテナ内で実行されるため、このディレクトリはインポートコンテナにリンクする必要がありますか?

その通りです。コンテナからインポートを実行している場合は、そのイメージをコンテナからアクセス可能な場所に配置し、そのパスを使用する必要があります。

「いいね!」 1

最後の質問です。インポートサービスについてお話しいただいたので、サイトを再確認し、データベースをさらに詳しく調査したところ、添付ファイルが格納されている場所がわかりました。ただ、ページ内の以下の一文が少し心配になりました:

例えば、一部のフォーラムでは、投稿本文に言及せずにファイルを投稿に添付できる場合があります。インポートスクリプトは、投稿本文内の参照を置き換えることで添付ファイルを特定しますが、この場合、リンクされていない添付ファイルは除外されます。

私の場合、添付ファイルは wp_postsmeta テーブルに _wp_attached_file として格納されていました。ただし、その添付ファイルがリンクされている投稿自体の本文には、その添付ファイルについての言及がありません。ここでの関連付けは post_idmeta_id のみであるようです。これはつまり、これが「リンクされていない添付ファイル」と見なされ、除外されてしまうのでしょうか?