Миграция форума Phorum на Discourse

Если у вас есть старый форум Phorum и вы планируете миграцию на Discourse, то этот урок для вас. Процесс прост, и мы будем использовать официальный скрипт импорта Phorum. Давайте начнём.

На высоком уровне мы выполним следующие шаги:

  • Подготовка локальной среды разработки.
  • Экспорт базы данных из рабочей среды.
  • Импорт рабочей базы данных в локальный экземпляр Discourse.
  • Запуск скрипта импорта Phorum.

Что можно мигрировать

  • Категории
    • Все форумы и папки => Корневая категория
  • Темы и сообщения
  • Пользователи (со следующими атрибутами)
    • статус блокировки
    • имя пользователя
    • настоящее имя => имя
    • электронная почта
    • статус администратора
    • дата добавления
    • время последнего присутствия

Подготовка локальной среды разработки

Следуйте одному из этих руководств для установки самого Discourse и обратитесь к этому руководству, если возникнут проблемы.

Установите сервер базы данных MySQL;

Ubuntu 18.04:

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

После завершения установки MySQL проверьте его состояние:

$ systemctl status mysql.service

Если он не запущен, выполните следующее:

$ 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

Проверьте состояние служб:

$ brew services list

Вы должны увидеть что-то вроде этого:

...
mysql@5.7         started
...

В противном случае выполните следующее и проверьте снова:

$ brew services start mysql@5.7

Для Windows вы можете следовать официальному руководству по установке.

Эта среда будет нашим сервером Discourse.

Экспорт базы данных из рабочей среды:

Экспортируйте рабочую базу данных (с рабочего сервера Phorum):

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

Скопируйте дамп базы данных на сервер Discourse.

:bulb: Используйте scp или rsync для копирования базы данных. И, конечно, вы можете сначала сжать её в gzip.

Импорт рабочей базы данных на сервер Discourse

На сервере Discourse создайте базу данных:

$ mysql -u root

:bulb: Если у вашего пользователя базы данных есть пароль, используйте: mysql -u root -p, а затем введите пароль.

mysql> CREATE DATABASE phorum;

Убедитесь, что база данных создана:

mysql> SHOW DATABASES;

Вы должны увидеть что-то вроде этого:

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

Это пустая база данных. Наш следующий шаг — импортировать в неё рабочую базу данных.

$ mysql -u root phorum < phorum_dump.sql

Пока мы здесь, давайте получим префикс таблиц. Он понадобится нам позже:

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

Вы увидите что-то вроде этого:

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

Из вывода выше видно, что префикс — pw_.

Запуск скрипта импорта Phorum

Сначала установите зависимости импортера:

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

Теперь настройте скрипт под наши требования. В нашем примере это будет выглядеть так:

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

# ...

host: "localhost",
username: "root",
password: "", # Измените это, если у вас есть пароль для базы данных MySQL
database: PHORUM_DB

Если вы хотите создать перенаправление URL, раскомментируйте следующее:

# 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

Это будет выглядеть так:

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

Запустите импортер с чистым экземпляром Discourse:

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

Импортер подключится к серверу MySQL и выполнит миграцию нашей базы данных Phorum в базу данных Discourse.

Запустите сервер Discourse после завершения импорта:

$ bundle exec rails server

Запустите Sidekiq для обработки мигрированных данных:

$ bundle exec sidekiq

:bulb: Вы можете отслеживать прогресс Sidekiq по адресу http://localhost:3000/sidekiq/queues.

Настройте ваш производственный сервер Discourse, следуя этому уроку.

Выполните резервное копирование базы данных Discourse и загрузите её на ваш производственный сервер Discourse, следуя этому уроку.

Готово :tada:

7 лайков

Я собираюсь приступить к миграции форума Phorum в Discourse. Я хотел бы сохранить файлы, прикрепленные к сообщениям (в основном изображения). Похоже, что в текущем скрипте миграции это не поддерживается. Кто-нибудь уже занимался этим вопросом?

1 лайк

Я внес несколько изменений в скрипт миграции для «Phorum», включая перенос вложений, файлов и загруженных материалов. Запрос на слияние находится здесь:

1 лайк

Спасибо за скрипты!

Однако мне кажется, что руководство довольно сырое и непонятное. Мне пришлось обратиться, например, к руководству по миграции с Xenforo, чтобы понять, что именно вы здесь предлагаете. Позвольте добавить недостающие шаги:

  • Убедитесь, что Discourse запущен и работает.
  • Создайте дамп базы данных mysqldump из исходного Phorum — всё понятно, всё хорошо.
  • Скопируйте дамп базы данных в папку Discourse: docker cp /path/to/backup/phorum_db.sql.gz app:/shared/phorum_db.sql.gz (предполагая, что имя стандартного контейнера — app).
    А вот и недостающие части:
  • На самом деле зайдите в контейнер Docker Discourse и установите там MySQL:
docker exec -it app bash
apt-get update && apt-get upgrade
# pv просто для удобства отображения прогресса, lsb-release требуется чем-то
 apt-get install -y lsb-release pv mariadb-server mariadb-client libmariadb-dev
 service mariadb start

Обратите внимание: установка MySQL немного сложнее, но MariaDB должна работать так же хорошо.

Затем создайте базу данных: mysqlCREATE database phorum.

Затем заполните её из резервной копии: pv phorum_db.sql.gz | gunzip | mysql phorum (если дамп в чистом SQL, gunzip не нужен).

Добавьте поддержку MySQL в Ruby:

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

Измените данные в скрипте миграции (учётные данные базы данных, префикс, постоянные ссылки):

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

А затем вернитесь к руководству в исходном посте — там всё хорошо:

Запустите импортёр с чистой копией Discourse:

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

Если база данных Discourse не совсем чистая, лучше предварительно очистить её командой bundle exec rake db:drop db:create db:migrate.

Если возникает ошибка “PG::ConnectionBad: connection to server on socket “/var/run/postgresql/.s.PGSQL.5432” failed: FATAL: Peer authentication failed for user “discourse” (PG::ConnectionBad)”:

  1. Если вы получаете ошибку 'Peer authentication failed for user "discourse"':
  2. Отредактируйте файл /etc/postgresql/13/main/pg_hba.conf
  3. Замените все значения ‘peer’ на ‘trust’ и сохраните файл
  4. Перезагрузите сервер PostgreSQL: /etc/init.d/postgresql reload (или, возможно, psql -U postgres -c "SELECT pg_reload_conf();", но иногда это не срабатывало у меня).

Сначала выполняются миграции пользователей, что может быть относительно медленно (~1,2 тыс. пользователей в минуту, согласно выводу скрипта. У меня было 100 тысяч пользователей, так что…). Затем создаются категории, и начинается миграция сообщений и тем (такая же скорость, ~1,2 тыс./мин), но уже на этом этапе вы можете зайти на сайт и посмотреть, как всё выглядит.

Похоже, это работает намного плавнее, чем я ожидал для такого древнего движка, как Phorum. Похоже, что личные сообщения (PM) не мигрируются, но для меня это, по крайней мере, не является критичным препятствием.

Ещё раз спасибо за скрипт и усилия!

Сложно написать руководство для чего-то настолько запутанного, которое охватывало бы все шаги. Определить, какие именно детали нужно объяснить конкретному пользователю, — задача нетривиальная. Молодец, что нашёл другое руководство с недостающими частями.

Можно было бы включить шаблон MySQL для установки MySQL или, возможно, подключиться к уже установленному серверу MySQL (так делаю обычно я).

Если захотите, можете посмотреть на другие скрипты, которые импортируют ЛС, чтобы использовать их в качестве примера.