Migrate a bbPress WordPress plugin forum to Discourse

I recently did a bbPress database migration successfully using Discourse’s inbuilt migration script. Now I’m going to share it as a step-by-step tutorial.

Note: This tutorial is for the bbPress plugin, not the legacy standalone version of bbPress.

What data can be imported?

  • Users (including anonymous users)
  • Categories
  • Topics
  • Posts
  • Private Messages (via BuddyPress)
  • Attachments
  • Permalinks

Before starting the migration set a development environment on your machine (or inside a virtual machine) and run the import there instead of inside the docker container. When I tried it inside docker container I got peer authentication failed issue. So I strongly recommending you that you use a development machine. See the macOS or Ubuntu / Debian installation guide for development.

Discourse requires Ruby 3.4+. You can check your Ruby version with:

ruby -v

Now we need to install the libmysqlclient-dev dependency in order to be able to use the mysql2 gem.

sudo apt-get install libmysqlclient-dev

After the successful installation go to your Discourse development installation path (typically ~/discourse).

cd ~/discourse

Configuring the database connection

The bbPress import script reads all database connection settings from environment variables. You do not need to edit the script file. The following environment variables are supported:

Variable Default Description
BBPRESS_HOST localhost MySQL database host
BBPRESS_USER root MySQL username
BBPRESS_PW (empty) MySQL password
BBPRESS_DB bbpress MySQL database name
BBPRESS_PREFIX wp_ WordPress table prefix
BBPRESS_ATTACHMENTS_DIR /path/to/attachments Path to bbPress attachments directory

If you are migrating your database from localhost you typically only need to set the database name:

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

If you are migrating your database from an external server you’ll also need to set the host, username, and password:

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

Congratulations! Your database successfully migrated from bbPress to Discourse :clap: :wave: :boom:

Now take a backup from admin page /admin/backups and import it in your live Discourse website.


After you moved your bbPress forum to Discourse if you are still going to use your WordPress website as primary site and you’d like to connect it with Discourse then install Discourse’s official WordPress plugin.

Last edited by @JammyDodger 2024-05-27T14:54:29Z

Check documentPerform check on document:
16개의 좋아요

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)

Thanks for this useful tutorial - worked for me although I have a couple of small issues:

  1. The install process seemed to install postgres 11 and Discourse hosted version support postgres 10, so that’s giving them a bit of a headache!

  2. My imported users don’t seem to be able to log into Discourse with their WordPress credentials - I tried it with my own user account, both with the username and the email address, but neither work. I can log into WordPress fine and the user account is present in Discourse, with the associated forum threads. Something changed with passwords/auth maybe?

Are you using SSO from WordPress?

This requires the migrate password plugin. Did you install that?

3개의 좋아요

Hi Michael,

No, that is the first reference I’ve found to the plugin, so thank you for highlighting it - maybe I missed a step somewhere! Thanks for sharing I will take a closer look tomorrow when my eyes aren’t quite so tired!

Ruth

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_id와 meta_id가 유일한 연결고리인 것 같습니다. 그렇다면 이것이 "연결되지 않은 첨부파일"에 해당하며 제외되는 것일까요?