نقل منتدى Phorum إلى Discourse

If you have an old Phorum forum and thinking to migrate to Discourse, then this tutorial is for you. The process is straightforward and we will be using the official Phorum Importer script. Let’s get started.

On a high level, we will do the following.

  • Preparing the local development environment.
  • Exporting the database from the production environment.
  • Importing the production database to a local Discourse instance.
  • Running the Phorum importer script.

What can be migrated

  • Categories
    • Every forums and folders => Root category
  • Topics & Posts
  • Users (with the following attributes)
    • banned status
    • username
    • real name => name
    • email
    • admin status
    • date added
    • last active

Preparing Local Development Environment

Follow one of these guides to install Discourse itself and consult this guide if you have any problems.

Install MySQL DB server;

Ubuntu 18.04:

$ sudo apt update
$ sudo apt install mysql-server -y

After finishing installing MySQL, check its status:

$ systemctl status mysql.service

If it is not running, run the following:

$ sudo systemctl start mysql

MacOS:

$ brew install mysql@5.7
$ echo 'export PATH="/usr/local/opt/mysql@5.7/bin:$PATH"' >> ~/.bash_profile
$ source ~/.bash_profile

Check the services status:

$ brew services list

You should see something like this:

...
mysql@5.7         started
...

Otherwise, run the following and check again:

$ brew services start mysql@5.7

For Windows, you can follow the official installation guide.

This environment will be our Discourse server.

Exporting The Database from Production Environment:

Export the production database (from Phorum production server):

$ mysqldump -u USER_NAME -p DATABASE_NAME > phorum_dump.sql

Copy the database dump to the Discourse server.

:bulb: Use scp or rsync to copy the database. And of course, you can gzip it first.

Importing The Production Database to Discourse server

On Discourse server, Create a database:

$ mysql -u root

:bulb: If your database user has a password you should use: mysql -u root -p then type your password.

mysql> CREATE DATABASE phorum;

Make sure that the database is created:

mysql> SHOW DATABASES;

You should see something like this:

+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| phorum             |
| sys                |
+--------------------+
5 rows in set (0.04 sec)

This is an empty database. Our next step is to import the production database into it.

$ mysql -u root phorum < phorum_dump.sql

While we are here, let’s get the table prefix. We will need it later:

$ mysql -u root
mysql> USE phorum;
mysql> SHOW TABLES;

You will see something like this:

+---------------------------+
| Tables_in_phorum          |
+---------------------------+
| pw_banlists           |
| pw_files              |
| pw_forum_group_xref   |
| pw_forums             |
| pw_groups             |
| pw_messages           |
| pw_messages_edittrack |
| pw_pm_buddies         |
| pw_pm_folders         |
| pw_pm_messages        |
| pw_pm_xref            |
| pw_search             |
| pw_settings           |
| pw_subscribers        |
| pw_user_custom_fields |
| pw_user_group_xref    |
| pw_user_newflags      |
| pw_user_permissions   |
| pw_users              |
+---------------------------+
19 rows in set (0.00 sec)

From the output above you can see that the prefix is pw_.

Running Phorum Importer Script

First, install the importer dependencies:

$ cd ~/discourse
$ echo "gem 'mysql2', require: false" >> Gemfile
$ bundle install

Now let’s configure the script to fits our requirements. In our example this will do:

PHORUM_DB = "phorum"
TABLE_PREFIX = "pw_"
BATCH_SIZE = 1000

# ...

host: "localhost",
username: "root",
password: "", # Change this if you have a password for MySQL database
database: PHORUM_DB

If you want to create a url redirecting, then you should uncomment the following:

# categories.each do |category|
#   Permalink.create(url: "list.php?#{category['id']}", category_id: category_id_from_imported_category_id(category['id'].to_i))
# end

#...

# results.each do |post|
#   if post['parent_id'] == 0
#     topic = topic_lookup_from_imported_post_id(post['id'].to_i)
#     Permalink.create(url: "read.php?#{post['category_id']},#{post['id']}", topic_id: topic[:topic_id].to_i)
#   end
# end

It will be like this:

categories.each do |category|
  Permalink.create(url: "list.php?#{category['id']}", category_id: category_id_from_imported_category_id(category['id'].to_i))
end

#...

results.each do |post|
  if post['parent_id'] == 0
    topic = topic_lookup_from_imported_post_id(post['id'].to_i)
    Permalink.create(url: "read.php?#{post['category_id']},#{post['id']}", topic_id: topic[:topic_id].to_i)
  end
end

Run the importer with a clean Discourse instance:

bundle exec rake db:drop db:create db:migrate
bundle exec ruby script/import_scripts/phorum.rb

The importer will connect to the MySQL server and migrates our Phorum database to Discourse database.

Start Discourse server after the importer finish importing:

$ bundle exec rails server

Start Sidekiq to process the migrated data:

$ bundle exec sidekiq

:bulb: You can monitor sidekiq progress at http://localhost:3000/sidekiq/queues.

Setup your Discourse production server by following this tutorial.

Perform a backup for Discourse database and upload it to your Discourse production server by following this tutorial.

It’s done :tada:

7 إعجابات

I’m about to start work on migrating a Phorum forum to Discourse. I would like to preserve files attached to posts (mostly pictures). Looks like this is not supported in the current migration script. Has anyone noodled on that already?

إعجاب واحد (1)

I’ve made a couple tweaks to the migration script for “phorum” including migrating attachments/files/uploads. The pull request is here:

إعجاب واحد (1)

شكراً على البرامج النصية!

ومع ذلك، أشعر أن الدليل خام وغير واضح. اضطررت إلى الرجوع إلى، على سبيل المثال، دليل ترحيل XenForo لفهم ما تقترحه هنا بالفعل. دعني أضف بعض الخطوات المفقودة:

  • تشغيل Discourse
  • إنشاء mysqldump من Phorum الأصلي - كل شيء واضح، كل شيء جيد.
  • نسخ تفريغ قاعدة البيانات إلى مجلد Discourse docker cp/path/to/backup/phorum_db.sql.gz app:/shared/phorum_db.sql.gz (بافتراض app كاسم حاوية قياسي)
    وهنا الأجزاء المفقودة:
  • الدخول فعليًا إلى حاوية Docker الخاصة بـ Discourse وتثبيت MySQL هناك:
docker exec -it app bash
apt-get update && apt-get upgrade
# pv للراحة فقط لعرض التقدم، lsb-release مطلوب لشيء ما
apt-get install -y lsb-release pv mariadb-server mariadb-client libmariadb-dev
service mariadb start

لاحظ أن تثبيت MySQL أكثر تعقيدًا بعض الشيء، ولكن Mariadb يجب أن يعمل بشكل جيد.

ثم قم بإنشاء قاعدة بيانات: mysqlCREATE database phorum.

ثم املأها من النسخ الاحتياطي: pv phorum_db.sql.gz | gunzip | mysql phorum (لا حاجة لـ gunzip إذا كان التفريغ الخاص بك هو sql عادي)

أضف دعم MySql إلى Ruby:

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

تعديل البيانات في البرنامج النصي للترحيل (بيانات اعتماد قاعدة البيانات، البادئة، الروابط الدائمة):

nano /var/www/discourse/script/import_scripts/phorum.rb

ثم العودة إلى دليل المنشور الأصلي، كل شيء جيد هناك:

تشغيل المستورد باستخدام نسخة Discourse نظيفة:

git config --global --add safe.directory /var/www/discourse
bundle exec ruby script/import_scripts/phorum.rb

إذا لم تكن قاعدة بيانات Discourse نظيفة حقًا، فمن الأفضل تنظيفها باستخدام bundle exec rake db:drop db:create db:migrate مسبقًا.

إذا فشل مع “PG::ConnectionBad: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL: Peer authentication failed for user "discourse" (PG::ConnectionBad)”:

  1. إذا حصلت على الخطأ 'Peer authentication failed for user "discourse"':
  2. قم بتحرير الملف /etc/postgresql/13/main/pg_hba.conf
  3. قم بتغيير كل ‘peer’ إلى ‘trust’ واحفظ الملف
  4. أعد تحميل خادم postgres: /etc/init.d/postgresql reload (أو ربما psql -U postgres -c "SELECT pg_reload_conf();", ولكن هذا كان يفشل معي أحيانًا)

أولاً، يقوم بتشغيل ترحيلات المستخدمين التي قد تكون بطيئة نسبيًا (~ 1.2 ألف مستخدم/دقيقة وفقًا لمخرجات البرنامج النصي. كان لدي 100 ألف مستخدم، لذا…). ثم يقوم بإنشاء فئات ويبدأ في ترحيل الرسائل والمواضيع (نفس السرعة، ~ 1.2 ألف/دقيقة)، ولكن في هذه المرحلة يمكنك بالفعل الوصول إلى موقع الويب ورؤية كيف يبدو.

يبدو أسهل بكثير مما كنت أتوقعه لمحرك قديم مثل Phorum. يبدو أنه لا يوجد ترحيل للرسائل الخاصة (PM)، ولكن لا ينبغي أن يكون ذلك عائقًا بالنسبة لي على الأقل.

شكراً مرة أخرى على البرنامج النصي والجهود!

من الصعب كتابة دليل لشيء معقد للغاية يغطي جميع الخطوات. معرفة القطع التي قد يحتاج المستخدم المعين إلى إخباره بها أمر معقد. عمل جيد في العثور على دليل آخر بالقطع المفقودة.

ربما كان بإمكانك تضمين قالب mysql لتثبيت mysql، أو ربما كنت ستصل إلى خادم mysql مثبت بالفعل بطريقة ما (وهو ما أفعله عادةً).

إذا أردت، يمكنك إلقاء نظرة على بعض البرامج النصية الأخرى التي تستورد الرسائل الخاصة (PM) لاستخدامها كمثال.