Migrare un forum Phorum a 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 Mi Piace

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 Mi Piace

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

1 Mi Piace

Grazie per gli script!

Tuttavia, ritengo che il manuale sia piuttosto grezzo e poco chiaro. Ho dovuto fare riferimento, ad esempio, alla guida alla migrazione di Xenforo per capire effettivamente cosa suggerisci qui. Lascia che aggiunga alcuni passaggi mancanti:

  • Avere Discourse attivo e funzionante
  • Creare mysqldump dal Phorum originale - tutto chiaro, tutto a posto.
  • Copiare il dump del database nella cartella di Discourse docker cp/path/to/backup/phorum_db.sql.gz app:/shared/phorum_db.sql.gz (assumendo app come nome contenitore standard)
    E qui le parti mancanti:
  • Accedere effettivamente al container Docker di Discourse e installare MySQL lì:
docker exec -it app bash
apt-get update && apt-get upgrade
# pv solo per comodità per visualizzare l'avanzamento, lsb-release è richiesto da qualcosa
apt-get install -y lsb-release pv mariadb-server mariadb-client libmariadb-dev
service mariadb start

Nota che l’installazione di MySQL è un po’ più complicata, ma Mariadb dovrebbe funzionare ugualmente bene.

Quindi creare un database: mysqlCREATE database phorum.

Quindi riempirlo dal backup: pv phorum_db.sql.gz | gunzip | mysql phorum (non è necessario gunzip se il tuo dump è sql puro)

Aggiungere il supporto MySql a Ruby:

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

Modificare i dati nello script di migrazione (credenziali del database, prefisso, permalink):

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

E poi tornare alla guida del post originale, tutto a posto lì:

Eseguire l’importatore con un’istanza Discourse pulita:

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

Se il tuo database Discourse non è veramente pulito, è meglio pulirlo prima con bundle exec rake db:drop db:create db:migrate.

Se fallisce con “PG::ConnectionBad: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL: Peer authentication failed for user "discourse" (PG::ConnectionBad)”:

  1. Se ricevi l’errore 'Peer authentication failed for user \"discourse\"':
  2. Modifica il file /etc/postgresql/13/main/pg_hba.conf
  3. cambia tutti i ‘peer’ in ‘trust’ e salva il file
  4. ricarica il server postgres: /etc/init.d/postgresql reload (o forse psql -U postgres -c \"SELECT pg_reload_conf();\", ma a volte questo mi dava errore)

Prima esegue le migrazioni degli utenti che potrebbero essere relativamente lente (~1.2k utenti/minuto secondo l’output dello script. Avevo 100k utenti, quindi…). Poi crea le categorie e inizia a migrare messaggi e argomenti (stessa velocità, ~1.2k/minuto), ma a questo punto puoi già accedere al sito web e vedere come appare.

Sembra molto più fluido di quanto mi aspetterei per un motore così antico come Phorum. Sembra che non ci sia migrazione di messaggi privati (PM), ma almeno per me non dovrebbe essere un blocco.

Grazie ancora per lo script e per gli sforzi!

È difficile scrivere una guida per qualcosa di così complicato che copra tutti i passaggi. Capire esattamente quali pezzi un particolare utente potrebbe aver bisogno che gli vengano detti è complesso. Buon lavoro nel trovare un’altra guida con i pezzi mancanti.

Potresti essere stato in grado di includere il template mysql per installare mysql, o forse avresti avuto accesso a un server mysql già installato in qualche modo (cosa che faccio di solito).

Se volessi, potresti guardare alcuni altri script che importano i PM per usarli come esempio.