Migrieren Sie ein Phorum-Forum zu 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 „Gefällt mir“

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 „Gefällt mir“

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

1 „Gefällt mir“

Vielen Dank für die Skripte!

Ich finde jedoch, dass das Handbuch ziemlich roh und unklar ist. Ich musste mich z. B. am Xenforo Migrationsleitfaden orientieren, um tatsächlich zu verstehen, was Sie hier vorschlagen. Lassen Sie mich einige fehlende Schritte hinzufügen:

  • Discourse am Laufen haben
  • Erstellen Sie einen mysqldump vom ursprünglichen Phorum - alles klar, alles gut.
  • Kopieren Sie den Datenbank-Dump in den Discourse-Ordner docker cp/path/to/backup/phorum_db.sql.gz app:/shared/phorum_db.sql.gz (unter der Annahme, dass app der Standardcontainername ist)
    Und hier die fehlenden Teile:
  • Springen Sie tatsächlich in den Discourse Docker Container und installieren Sie MySQL dort:
docker exec -it app bash
apt-get update && apt-get upgrade
# pv nur zur Bequemlichkeit, um den Fortschritt anzuzeigen, lsb-release wird von etwas benötigt
apt-get install -y lsb-release pv mariadb-server mariadb-client libmariadb-dev
service mariadb start

Beachten Sie, dass die MySQL-Installation etwas kniffliger ist, aber Mariadb sollte genauso gut funktionieren.

Erstellen Sie dann eine Datenbank: mysqlCREATE database phorum.

Füllen Sie sie dann aus dem Backup: pv phorum_db.sql.gz | gunzip | mysql phorum (kein gunzip erforderlich, wenn Ihr Dump reines SQL ist)

Fügen Sie MySql-Unterstützung zu Ruby hinzu:

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

Ändern Sie die Daten im Migrationsskript (Datenbankanmeldeinformationen, Präfix, Permalinks):

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

Und dann zurück zum ursprünglichen Leitfaden, alles gut dort:

Führen Sie den Importer mit einer sauberen Discourse-Instanz aus:

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

Wenn Ihre Discourse-Datenbank nicht wirklich sauber ist, bereinigen Sie sie besser vorher mit bundle exec rake db:drop db:create db:migrate.

Wenn es mit “PG::ConnectionBad: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL: Peer authentication failed for user "discourse" (PG::ConnectionBad)” fehlschlägt:

  1. Wenn Sie den Fehler 'Peer authentication failed for user "discourse"' erhalten:
  2. Bearbeiten Sie die Datei /etc/postgresql/13/main/pg_hba.conf
  3. Ändern Sie alle ‘peer’ in ‘trust’ und speichern Sie die Datei
  4. Laden Sie den Postgres-Server neu: /etc/init.d/postgresql reload (oder vielleicht psql -U postgres -c "SELECT pg_reload_conf();", aber das schlug bei mir manchmal fehl)

Zuerst werden die Benutzermigrationen ausgeführt, die relativ langsam sein können (~1,2k Benutzer/Minute laut Skriptausgabe. Ich hatte 100k Benutzer, also…). Dann werden Kategorien erstellt und mit der Migration von Nachrichten und Themen begonnen (gleiche Geschwindigkeit, ~1,2k/Minute), aber zu diesem Zeitpunkt können Sie bereits auf die Website zugreifen und sehen, wie sie aussieht.

Scheint viel reibungsloser zu laufen, als ich es von einer so alten Engine wie Phorum erwartet hätte. Es scheint keine Migration von privaten Nachrichten (PM) zu geben, aber das sollte für mich zumindest kein Hindernis sein.

Nochmals vielen Dank für das Skript und die Bemühungen!

Es ist schwierig, eine Anleitung für etwas so Kompliziertes zu schreiben, die alle Schritte abdeckt. Herauszufinden, welche Teile einem bestimmten Benutzer mitgeteilt werden müssen, ist komplex. Gute Arbeit, eine weitere Anleitung mit den fehlenden Teilen gefunden zu haben.

Vielleicht hättest du die MySQL-Vorlage einbeziehen können, um MySQL zu installieren, oder vielleicht hättest du auf einen bereits installierten MySQL-Server zugegriffen (was ich normalerweise tue).

Wenn du wolltest, könntest du dir andere Skripte ansehen, die PMs importieren, um sie als Beispiel zu verwenden.