Migrer un forum Phorum vers 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 « J'aime »

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 « J'aime »

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

1 « J'aime »

Merci pour les scripts !

Cependant, j’ai l’impression que le manuel est assez brut et peu clair. J’ai dû me référer, par exemple, au guide de migration Xenforo pour bien comprendre ce que vous suggérez ici. Laissez-moi ajouter quelques étapes manquantes :

  • Avoir Discourse opérationnel
  • Créer un mysqldump du Phorum original - tout est clair, tout va bien.
  • Copier le dump de la base de données dans le dossier Discourse docker cp/path/to/backup/phorum_db.sql.gz app:/shared/phorum_db.sql.gz (en supposant app comme nom de conteneur standard)
    Et voici les parties manquantes :
  • Accéder au conteneur Docker de Discourse et y installer MySQL :
docker exec -it app bash
apt-get update && apt-get upgrade
# pv juste pour afficher la progression, lsb-release est requis par quelque chose
apt-get install -y lsb-release pv mariadb-server mariadb-client libmariadb-dev
service mariadb start

Notez que l’installation de MySQL est un peu plus compliquée, mais Mariadb devrait fonctionner aussi bien.

Ensuite, créez une base de données : mysqlCREATE database phorum.

Puis remplissez-la à partir de la sauvegarde : pv phorum_db.sql.gz | gunzip | mysql phorum (pas besoin de gunzip si votre dump est un sql brut)

Ajoutez le support MySql à Ruby :

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

Modifiez les données dans le script de migration (identifiants de base de données, préfixe, permaliens) :

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

Et ensuite, revenez au guide du post original, tout va bien là-bas :

Lancez l’importateur avec une instance Discourse propre :

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

Si votre base de données Discourse n’est pas vraiment propre, il est préférable de la nettoyer avec bundle exec rake db:drop db:create db:migrate au préalable.

Si cela échoue avec “PG::ConnectionBad: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL: Peer authentication failed for user "discourse" (PG::ConnectionBad)” :

  1. Si vous obtenez l’erreur 'Peer authentication failed for user \"discourse\"' :
  2. Modifiez le fichier /etc/postgresql/13/main/pg_hba.conf
  3. changez tous les ‘peer’ en ‘trust’ et enregistrez le fichier
  4. rechargez le serveur postgres : /etc/init.d/postgresql reload (ou peut-être psql -U postgres -c \"SELECT pg_reload_conf();\", mais cela échouait parfois pour moi)

D’abord, il exécute les migrations d’utilisateurs qui peuvent être relativement lentes (~1.2k utilisateurs/minute selon la sortie du script. J’avais 100k utilisateurs, donc…). Ensuite, il crée les catégories et commence à migrer les messages et les sujets (même vitesse, ~1.2k/minute), mais à ce stade, vous pouvez déjà accéder au site web et voir à quoi cela ressemble.

Cela semble beaucoup plus fluide que ce à quoi je m’attendrais pour un moteur aussi ancien que Phorum. Il semble qu’il n’y ait pas de migration des messages privés (PM), mais cela ne devrait pas être un obstacle pour moi au moins.

Merci encore pour le script et les efforts !

Il est difficile d’écrire un guide pour quelque chose d’aussi compliqué qui couvre toutes les étapes. Déterminer exactement quelles pièces un utilisateur particulier pourrait avoir besoin de connaître est complexe. Bon travail pour trouver un autre guide avec les pièces manquantes.

Vous auriez peut-être pu inclure le modèle mysql pour installer mysql, ou peut-être accéder à un serveur mysql déjà installé d’une manière ou d’une autre (ce que je fais habituellement).

Si vous le souhaitiez, vous pourriez examiner d’autres scripts qui importent des MP pour vous en servir d’exemple.