Migrar un foro de 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 Me gusta

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 me gusta

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

1 me gusta

¡Gracias por los scripts!

Sin embargo, siento que el manual está bastante crudo y poco claro. Tuve que consultar, por ejemplo, la guía de migración de Xenforo para entender realmente qué sugieres aquí. Permíteme agregar algunos pasos faltantes:

  • Tener Discourse funcionando
  • Crear un mysqldump del Phorum original - todo claro, todo bien.
  • Copiar el volcado de la base de datos a la carpeta de Discourse docker cp/path/to/backup/phorum_db.sql.gz app:/shared/phorum_db.sql.gz (asumiendo app como nombre de contenedor estándar)
    Y aquí las partes faltantes:
  • Entrar realmente al contenedor Docker de Discourse e instalar MySQL allí:
docker exec -it app bash
apt-get update && apt-get upgrade
# pv solo para conveniencia para mostrar el progreso, lsb-release es requerido por algo
apt-get install -y lsb-release pv mariadb-server mariadb-client libmariadb-dev
service mariadb start

Nota: la instalación de MySQL es un poco más complicada, pero Mariadb debería funcionar igual de bien.

Luego, crea una base de datos: mysqlCREATE database phorum.

Luego, llénala desde la copia de seguridad: pv phorum_db.sql.gz | gunzip | mysql phorum (no es necesario gunzip si tu volcado es sql puro).

Agrega soporte de MySQL a Ruby:

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

Modifica los datos en el script de migración (credenciales de la base de datos, prefijo, permalinks):

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

Y luego, volviendo a la guía de la publicación original, todo está bien allí:

Ejecuta el importador con una instancia limpia de Discourse:

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

Si tu base de datos de Discourse no está realmente limpia, es mejor limpiarla con bundle exec rake db:drop db:create db:migrate de antemano.

Si falla 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. Si obtienes el error 'Peer authentication failed for user \"discourse\"':
  2. Edita el archivo /etc/postgresql/13/main/pg_hba.conf
  3. cambia todos los ‘peer’ a ‘trust’ y guarda el archivo
  4. recarga el servidor postgres: /etc/init.d/postgresql reload (o quizás psql -U postgres -c \"SELECT pg_reload_conf();\", pero esto a veces me fallaba).

Primero, ejecuta las migraciones de usuarios, que pueden ser relativamente lentas (~1.2k usuarios/minuto según la salida del script. Tuve 100k usuarios, así que…). Luego, crea categorías y comienza a migrar mensajes y temas (misma velocidad, ~1.2k/minuto), pero en este punto ya puedes acceder al sitio web y ver cómo se ve.

Parece mucho más fluido de lo que esperaba para un motor tan antiguo como Phorum. Parece que no hay migración de Mensajes Privados (PM), pero al menos no debería ser un obstáculo para mí.

¡Gracias de nuevo por el script y los esfuerzos!

Es difícil escribir una guía para algo tan complicado que cubra todos los pasos. Averiguar qué piezas necesita que se le digan a un usuario en particular es complejo. Buen trabajo encontrando otra guía con las piezas que faltan.

Es posible que hayas podido incluir la plantilla de mysql para instalar mysql, o tal vez acceder a un servidor mysql que ya estaba instalado de alguna manera (lo que suelo hacer).

Si quisieras, podrías mirar algunos otros scripts que importan PM para usarlos como ejemplo.