Migrar un foro de Phorum a Discourse

Si tienes un foro antiguo de Phorum y estás pensando en migrar a Discourse, entonces este tutorial es para ti. El proceso es sencillo y utilizaremos el script importador oficial de Phorum. Comencemos.

En términos generales, haremos lo siguiente:

  • Preparar el entorno de desarrollo local.
  • Exportar la base de datos desde el entorno de producción.
  • Importar la base de datos de producción a una instancia local de Discourse.
  • Ejecutar el script importador de Phorum.

Qué se puede migrar

  • Categorías
    • Cada foro y carpeta => Categoría raíz
  • Temas y Publicaciones
  • Usuarios (con los siguientes atributos)
    • estado de prohibición
    • nombre de usuario
    • nombre real => nombre
    • correo electrónico
    • estado de administrador
    • fecha de incorporación
    • última actividad

Preparación del entorno de desarrollo local

Sigue una de estas guías para instalar Discourse en sí mismo y consulta esta guía si tienes algún problema.

Instala el servidor de base de datos MySQL;

Ubuntu 18.04:

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

Después de finalizar la instalación de MySQL, verifica su estado:

$ systemctl status mysql.service

Si no se está ejecutando, ejecuta lo siguiente:

$ 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

Verifica el estado de los servicios:

$ brew services list

Deberías ver algo como esto:

...
mysql@5.7         started
...

De lo contrario, ejecuta lo siguiente y verifica nuevamente:

$ brew services start mysql@5.7

Para Windows, puedes seguir la guía de instalación oficial.

Este entorno será nuestro servidor de Discourse.

Exportación de la base de datos desde el entorno de producción:

Exporta la base de datos de producción (desde el servidor de producción de Phorum):

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

Copia el volcado de la base de datos al servidor de Discourse.

:bulb: Usa scp o rsync para copiar la base de datos. Y, por supuesto, puedes comprimirla con gzip primero.

Importación de la base de datos de producción al servidor de Discourse

En el servidor de Discourse, crea una base de datos:

$ mysql -u root

:bulb: Si tu usuario de base de datos tiene una contraseña, deberías usar: mysql -u root -p y luego escribir tu contraseña.

mysql> CREATE DATABASE phorum;

Asegúrate de que la base de datos se haya creado:

mysql> SHOW DATABASES;

Deberías ver algo como esto:

+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| phorum             |
| sys                |
+--------------------+
5 filas en el conjunto (0.04 seg)

Esta es una base de datos vacía. Nuestro siguiente paso es importar la base de datos de producción en ella.

$ mysql -u root phorum < phorum_dump.sql

Mientras estamos aquí, obtengamos el prefijo de tabla. Lo necesitaremos más adelante:

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

Verás algo como esto:

+---------------------------+
| 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 filas en el conjunto (0.00 seg)

De la salida anterior puedes ver que el prefijo es pw_.

Ejecución del script importador de Phorum

Primero, instala las dependencias del importador:

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

Ahora configuremos el script para que se ajuste a nuestros requisitos. En nuestro ejemplo, esto hará:

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

# ...

host: "localhost",
username: "root",
password: "", # Cambia esto si tienes una contraseña para la base de datos MySQL
database: PHORUM_DB

Si deseas crear una redirección de URL, entonces deberías descomentar lo siguiente:

# 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

Será así:

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

Ejecuta el importador con una instancia limpia de Discourse:

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

El importador se conectará al servidor MySQL y migrará nuestra base de datos de Phorum a la base de datos de Discourse.

Inicia el servidor de Discourse después de que el importador termine de importar:

$ bundle exec rails server

Inicia Sidekiq para procesar los datos migrados:

$ bundle exec sidekiq

:bulb: Puedes monitorear el progreso de Sidekiq en http://localhost:3000/sidekiq/queues.

Configura tu servidor de producción de Discourse siguiendo este tutorial.

Realiza una copia de seguridad de la base de datos de Discourse y súbela a tu servidor de producción de Discourse siguiendo este tutorial.

¡Listo :tada:

7 Me gusta

Estoy a punto de comenzar a trabajar en la migración de un foro Phorum a Discourse. Me gustaría preservar los archivos adjuntos a las publicaciones (principalmente imágenes). Parece que esto no está soportado en el script de migración actual. ¿Alguien ya ha pensado en esto?

1 me gusta

He realizado algunos ajustes al script de migración para “phorum”, incluyendo la migración de archivos adjuntos/archivos/subidas. La solicitud de extracción está aquí:

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.