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:
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. Мои импортированные пользователи, похоже, не могут войти в Discourse с учётными данными WordPress — я попробовал со своей учётной записью, используя как имя пользователя, так и адрес электронной почты, но ни один из них не сработал. В WordPress я могу войти без проблем, и учётная запись присутствует в Discourse с соответствующими темами форума. Возможно, что-то изменилось с паролями/аутентификацией?

Вы используете SSO из WordPress?

Для этого требуется плагин migrate password. Вы его установили?

3 лайка

Привет, Майкл,

Нет, это первая ссылка на плагин, которую я нашла, так что спасибо, что обратили на это внимание — возможно, я где-то упустила шаг! Спасибо, что поделились, я завтра, когда глаза будут не так устали, посмотрю внимательнее!

Рут

3 лайка

Привет :waving_hand:

Можно ли также мигрировать загруженные пользователями изображения?
Плагин для загрузок пользователей — GD bbPress Attachments.

Ура :beers:

Скрипт, по-видимому, импортирует вложения.

Необходимо задать переменную окружения BB_PRESS_ATTACHMENTS_DIR с путем к папке с вложениями.

1 лайк

Загрузки плагина bbPress, похоже, хранятся в папке /uploads установки WordPress. Для этого использовался плагин 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. Значит ли это, что это «несвязанное вложение», которое будет пропущено?