Migrar um fórum Phorum para Discourse

Se você tem um fórum Phorum antigo e está pensando em migrar para o Discourse, este tutorial é para você. O processo é direto e usaremos o script oficial de importação do Phorum. Vamos começar.

Em alto nível, faremos o seguinte:

  • Preparar o ambiente de desenvolvimento local.
  • Exportar o banco de dados do ambiente de produção.
  • Importar o banco de dados de produção para uma instância local do Discourse.
  • Executar o script de importação do Phorum.

O que pode ser migrado

  • Categorias
    • Todos os fóruns e pastas => Categoria raiz
  • Tópicos e Mensagens
  • Usuários (com os seguintes atributos)
    • status de banido
    • nome de usuário
    • nome real => nome
    • e-mail
    • status de administrador
    • data de cadastro
    • última atividade

Preparando o Ambiente de Desenvolvimento Local

Siga um destes guias para instalar o próprio Discourse e consulte este guia se tiver algum problema.

Instale o servidor de banco de dados MySQL;

Ubuntu 18.04:

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

Após concluir a instalação do MySQL, verifique seu status:

$ systemctl status mysql.service

Se não estiver em execução, execute o seguinte:

$ 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

Verifique o status dos serviços:

$ brew services list

Você deve ver algo assim:

...
mysql@5.7         started
...

Caso contrário, execute o seguinte e verifique novamente:

$ brew services start mysql@5.7

Para o Windows, você pode seguir o guia de instalação oficial.

Este ambiente será nosso servidor Discourse.

Exportando o Banco de Dados do Ambiente de Produção:

Exporte o banco de dados de produção (do servidor de produção do Phorum):

$ mysqldump -u NOME_DO_USUARIO -p NOME_DO_BANCO_DE_DADOS > phorum_dump.sql

Copie o dump do banco de dados para o servidor Discourse.

:bulb: Use scp ou rsync para copiar o banco de dados. E, claro, você pode compactá-lo com gzip primeiro.

Importando o Banco de Dados de Produção para o Servidor Discourse

No servidor Discourse, crie um banco de dados:

$ mysql -u root

:bulb: Se o usuário do seu banco de dados tiver uma senha, você deve usar: mysql -u root -p e depois digitar sua senha.

mysql> CREATE DATABASE phorum;

Certifique-se de que o banco de dados foi criado:

mysql> SHOW DATABASES;

Você deve ver algo assim:

+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| phorum             |
| sys                |
+--------------------+
5 rows in set (0.04 sec)

Este é um banco de dados vazio. Nosso próximo passo é importar o banco de dados de produção para ele.

$ mysql -u root phorum < phorum_dump.sql

Enquanto estamos aqui, vamos obter o prefixo da tabela. Precisaremos dele mais tarde:

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

Você verá algo assim:

+---------------------------+
| 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)

Pela saída acima, você pode ver que o prefixo é pw_.

Executando o Script de Importação do Phorum

Primeiro, instale as dependências do importador:

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

Agora vamos configurar o script para atender às nossas necessidades. Em nosso exemplo, isso funcionará:

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

# ...

host: "localhost",
username: "root",
password: "", # Altere isso se você tiver uma senha para o banco de dados MySQL
database: PHORUM_DB

Se você quiser criar um redirecionamento de URL, deve descomentar o seguinte:

# 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

Ficará assim:

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

Execute o importador com uma instância limpa do Discourse:

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

O importador se conectará ao servidor MySQL e migrará nosso banco de dados Phorum para o banco de dados do Discourse.

Inicie o servidor do Discourse após o importador terminar a importação:

$ bundle exec rails server

Inicie o Sidekiq para processar os dados migrados:

$ bundle exec sidekiq

:bulb: Você pode monitorar o progresso do Sidekiq em http://localhost:3000/sidekiq/queues.

Configure seu servidor de produção do Discourse seguindo este tutorial.

Faça um backup do banco de dados do Discourse e carregue-o no seu servidor de produção do Discourse seguindo este tutorial.

Está feito :tada:

7 curtidas

Estou prestes a começar a trabalhar na migração de um fórum Phorum para o Discourse. Gostaria de preservar os arquivos anexados às postagens (principalmente imagens). Parece que isso não é suportado no script de migração atual. Alguém já pensou nisso?

1 curtida

Fiz alguns ajustes no script de migração para o “phorum”, incluindo a migração de anexos, arquivos e uploads. O pull request está aqui:

1 curtida

Obrigado pelos scripts!

No entanto, acho que o manual está bastante cru e pouco claro. Tive que consultar, por exemplo, o guia de migração do XenForo para realmente entender o que vocês sugerem aqui. Deixe-me adicionar algumas etapas que faltam:

  • Ter o Discourse instalado e funcionando
  • Criar o mysqldump do Phorum original - tudo claro, tudo bem.
  • Copiar o dump do banco de dados para a pasta do Discourse docker cp /path/to/backup/phorum_db.sql.gz app:/shared/phorum_db.sql.gz (assumindo app como nome padrão do contêiner)
    E aqui as partes que faltam:
  • Entrar no contêiner Docker do Discourse e instalar o MySQL lá:
docker exec -it app bash
apt-get update && apt-get upgrade
# pv apenas para conveniência para exibir o progresso, lsb-release é necessário por algo
apt-get install -y lsb-release pv mariadb-server mariadb-client libmariadb-dev
service mariadb start

Note que a instalação do MySQL é um pouco mais complicada, mas o Mariadb deve funcionar bem.

Em seguida, crie um banco de dados: mysqlCREATE database phorum.

Em seguida, preencha-o a partir do backup: pv phorum_db.sql.gz | gunzip | mysql phorum (não é necessário gunzip se o seu dump for sql puro).

Adicione suporte MySql ao Ruby:

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

Modifique os dados no script de migração (credenciais do banco de dados, prefixo, permalinks):

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

E então de volta ao guia do post original, tudo bem lá:

Execute o importador com uma instância limpa do Discourse:

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

Se o seu banco de dados Discourse não estiver realmente limpo, é melhor limpá-lo com bundle exec rake db:drop db:create db:migrate antes.

Se falhar com “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 você receber o erro 'Peer authentication failed for user "discourse"':
  2. Edite o arquivo /etc/postgresql/13/main/pg_hba.conf
  3. Mude todos os ‘peer’ para ‘trust’ e salve o arquivo
  4. Recarregue o servidor postgres: /etc/init.d/postgresql reload (ou talvez psql -U postgres -c "SELECT pg_reload_conf();", mas isso falhava para mim às vezes)

Primeiro, ele executa as migrações de usuários, que podem ser relativamente lentas (~1.2k usuários/minuto de acordo com a saída do script. Eu tinha 100k usuários, então…). Em seguida, ele cria categorias e começa a migrar mensagens e tópicos (mesma velocidade, ~1.2k/minuto), mas a essa altura você já pode acessar o site e ver como está.

Parece bem mais suave do que eu esperaria para um motor tão antigo quanto o Phorum. Parece que não há migração de Mensagens Privadas (PM), mas isso não deve ser um bloqueador para mim, pelo menos.

Obrigado novamente pelo script e pelos esforços!

É difícil escrever um guia para algo tão complicado que cubra todas as etapas. Descobrir exatamente quais partes um usuário específico pode precisar que lhe sejam ditas é complexo. Bom trabalho em encontrar outro guia com as partes que faltam.

Você poderia ter incluído o template do mysql para instalar o mysql, ou talvez você acessasse um servidor mysql que já estava instalado de alguma forma (o que eu costumo fazer).

Se você quisesse, poderia olhar alguns outros scripts que importam PMs para usar como exemplo.