Migrar un foro IPB 3.1 a Discourse

Hola Comunidad Discourse,

Quiero compartir mi experiencia importando un foro IPB 3.1 a Discourse 2.1, con la esperanza de que esto sea útil para otros.

Un breve resumen sobre la Comunidad:

  • Tema: Yii PHP Framework (discusiones y soporte relacionados con código)
  • Miembros: ~26k
  • Temas: ~64k
  • Publicaciones: ~293k

La importación tomó 27 horas y 46 minutos en una máquina con 16 GB de RAM y 4 núcleos de CPU.

Requisitos de la importación:

  • Mantener a los miembros, pero limpiar todas las cuentas de SPAM (~250k cuentas, de las cuales ~26k permanecen después de la limpieza)
  • Implementar SSO desde el sitio web (las cuentas de usuario no son gestionadas por Discourse)
  • Mantener temas, publicaciones y categorías con sus URLs originales para que los resultados de búsqueda web sigan funcionando, así como otros enlaces desde plataformas como Stackoverflow

Esto se basa en Migrating from Invision Power Board to Discourse - #23 by pfaffman, así que gracias a @pfaffman por el gran trabajo realizado en el importador.

Preparación

Exportar datos desde IPB

mysqldump <nombre_de_base_de_datos> > /tmp/ipb.sql
cd /var/www/yiiframework.com/forum/ && tar czvf uploads.tgz uploads/

Copie el volcado SQL y las subidas al nuevo servidor y colóquelos en /var/discourse/shared/standalone/.
Asumo aquí una configuración simple de Docker de Discourse.

¿Qué script usar?

Hay dos scripts de importación, ipboard.rb y ipboard3.rb; el script ipboard3.rb parece muy tosco y tampoco se ajusta al esquema de tablas que tenemos, así que opté por ipboard.rb.

La versión actual del script de importación ipboard.rb no maneja bien los archivos adjuntos y tampoco convierte las etiquetas de código, lo cual es muy importante para nosotros ya que hablamos mucho sobre código PHP. Por lo tanto, realicé los siguientes cambios en el script:

Hacer disponibles los archivos adjuntos subidos

El script de importación reemplaza los archivos adjuntos de las publicaciones con URLs al archivo subido.
Si planea mantener su instancia de IPB en línea en la URL donde estaba antes, puede simplemente especificar la URL (UPLOADS es una configuración del script de importación, ver más abajo) al directorio de subidas y ya está:

UPLOADS="https://www.yiiframework.com/forum/uploads"

Pero estamos importando a Discourse para eliminar completamente el foro antiguo, por lo que debemos colocar las subidas en otro lugar. Si está utilizando un proxy nginx frente a Discourse, puede configurarlo para servir los archivos subidos desde un directorio en el servidor. Coloque lo siguiente en la parte server de la configuración de nginx:

location /ipb_uploads/ {
    alias /var/www/ipb_uploads/;
}

Y configure la URL de los archivos adjuntos (ver más abajo) de la siguiente manera:

UPLOADS="https://forum.yiiframework.com/ipb_uploads"

Configurar MySQL en el contenedor de Discourse

Inicie una shell bash en el contenedor de la aplicación de Discourse:

docker exec -it app bash

Dentro del contenedor, instale MySQL e importe la base de datos:

apt-get install mysql-server mysql-client libmysqlclient-dev
service mysql start
echo "create database ipb" | mysql -uroot -p
mysql -uroot -p ipb < /shared/ipb.sql

Cuando intenté la primera importación para probar el script, tardó varios días en importar 200k usuarios, de los cuales sabíamos que una gran cantidad eran cuentas de SPAM, por lo que creamos algunas consultas SQL para eliminar cuentas que nunca habían publicado nada:

Tenga en cuenta que vamos a usar SSO, por lo que los usuarios eliminados se volverán a crear cuando inicien sesión.
Si no va a usar SSO, sus criterios para eliminar usuarios podrían ser diferentes.
Puede importar sus datos sin limpiarlos.

mysql -uroot -p
# luego aplique las consultas de limpieza

A continuación, necesitamos instalar las dependencias para el script de importación:

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

Para permitir el acceso a la base de datos de Discourse Postgres, reemplace peer con trust en /etc/postgresql/10/main/pg_hba.conf. Tenga en cuenta que 10 representa la versión de postgres; si el archivo no existe en su configuración, reemplace 10 con la versión de postgres que esté ejecutando actualmente.
Reinicie Postgres para cargar los cambios: service postgresql restart

Importando

Prepare los avatares y los archivos subidos:

mkdir /shared/imports
mv /shared/uploads.tgz /shared/imports
cd /shared/imports && tar xzvf uploads.tgz

Ejecute el script del importador:

cd /var/www/discourse
DB_HOST="localhost" DB_NAME="yiisite" DB_USER="root" DB_PW="root" TABLE_PREFIX="ipb_" IMPORT_AFTER="1970-01-01" UPLOADS="https://www.forum.yiiframework.com/ipb_uploads" AVATARS_DIR="/shared/imports/uploads/" USERDIR="user" bundle exec ruby script/import_scripts/ipboard.rb | tee import.log

Asegúrese de ajustar la URL de UPLOADS como se discutió anteriormente, ya que las subidas se incluirán en las publicaciones como enlaces al archivo de subida original.

Limpieza

Si todo salió bien, limpie con service mysql stop, apt-get purge mysql-server, rm -rf /var/lib/mysql

Configuración de redirección de URLs

Para mantener intactas las URLs existentes al foro, el script de importación crea enlaces permanentes (permalinks) para cada tema que reflejan la URL de los temas y categorías en IPB.
Sin embargo, estos permalinks no cubren enlaces a publicaciones específicas dentro de un tema o diferentes páginas.
Para que estas URLs funcionen correctamente, debe configurar algunas reglas de reescritura de URLs; hay 3 opciones:

  • Usar la configuración permalink normalizations en Discourse para eliminar partes innecesarias de las URLs
  • Reglas de reescritura en nginx, si tiene un proxy nginx frente a Discourse
  • Si el foro antiguo estaba en una URL/Hospedaje diferente que Discourse, puede tener un script personalizado para reescribir las URLs (esto es lo que hice)

Aquí está el código PHP que usamos para la redirección de URLs:

Recursos relacionados

18 Me gusta

Hola,

lo siento por revivir este tema antiguo, pero también estoy planeando migrar desde IPB (v3.4) a Discourse y estoy siguiendo esta guía howto. Así que decidí responder directamente en este tema en lugar de crear uno nuevo.

El paquete mysql ya no está en la distribución, así que seguí esta guía
básicamente:

wget http://repo.mysql.com/mysql-apt-config_0.8.13-1_all.deb
sudo dpkg -i mysql-apt-config_0.8.13-1_all.deb
sudo apt update
sudo apt install mysql-server mysql-client libmysqlclient-deb
service mysql start

pero luego obtengo el siguiente error
mysql: servicio no reconocido

¿Alguna idea de cómo puedo iniciar mysql?

Gracias

¿Hubo errores cuando ejecutaste los comandos que deberían haberlo instalado? Te recomiendo una búsqueda en Google.

Además, quizás quieras usar el script ipb que forma parte de Discourse en lugar del que se menciona en el OP.

¿Hay alguna actualización para este script porque no funcionará con IPB 4x y tampoco es compatible con Discourse, ya que la estructura de las tablas cambió y el script permanece como está?

1 me gusta

Estoy haciendo una importación de ipboard ahora. Tuve que eliminar algunas tablas y filas de algunas de las consultas. Parece que tienen muchas configuraciones de tabla diferentes.

Obtener las publicaciones sin procesar de ipb en markdown también es complicado.

Si tienes presupuesto, puedes contactarme. Podría darte el código que tengo para la importación que estoy haciendo ahora, pero probablemente necesitará trabajo para tu configuración particular.

2 Me gusta

to help you, IPB 4x tables is as follow:

mysql> SHOW TABLES;
+-------------------------------------------+
| Tables_in_ipboard                         |
+-------------------------------------------+
| ipb_bbcode_mediatag                       |
| ipb_ccs_folders                           |
| ipb_cms_blocks                            |
| ipb_cms_containers                        |
| ipb_cms_custom_database_1                 |
| ipb_cms_custom_database_2                 |
| ipb_cms_database_categories               |
| ipb_cms_database_comments                 |
| ipb_cms_database_fields                   |
| ipb_cms_database_fields_reciprocal_map    |
| ipb_cms_database_fields_thumbnails        |
| ipb_cms_database_reviews                  |
| ipb_cms_database_revisions                |
| ipb_cms_databases                         |
| ipb_cms_folders                           |
| ipb_cms_media                             |
| ipb_cms_media_folders                     |
| ipb_cms_page_database_map                 |
| ipb_cms_page_widget_areas                 |
| ipb_cms_pages                             |
| ipb_cms_template_conflicts                |
| ipb_cms_templates                         |
| ipb_cms_url_store                         |
| ipb_core_achievements_log                 |
| ipb_core_achievements_log_milestones      |
| ipb_core_achievements_rules               |
| ipb_core_acp_notifcations_dismissals      |
| ipb_core_acp_notifications                |
| ipb_core_acp_notifications_preferences    |
| ipb_core_acp_search_index                 |
| ipb_core_acp_tab_order                    |
| ipb_core_acronyms                         |
| ipb_core_admin_login_logs                 |
| ipb_core_admin_logs                       |
| ipb_core_admin_permission_rows            |
| ipb_core_advertisements                   |
| ipb_core_alerts                           |
| ipb_core_alerts_seen                      |
| ipb_core_announcements                    |
| ipb_core_anonymous_posts                  |
| ipb_core_api_keys                         |
| ipb_core_api_logs                         |
| ipb_core_api_webhook_fires                |
| ipb_core_api_webhooks                     |
| ipb_core_applications                     |
| ipb_core_approval_queue                   |
| ipb_core_archive_log                      |
| ipb_core_archive_restore                  |
| ipb_core_attachments                      |
| ipb_core_attachments_map                  |
| ipb_core_automatic_moderation_pending     |
| ipb_core_automatic_moderation_rules       |
| ipb_core_automatic_moderation_types       |
| ipb_core_badges                           |
| ipb_core_banfilters                       |
| ipb_core_bulk_mail                        |
| ipb_core_cache                            |
| ipb_core_club_pages                       |
| ipb_core_clubs                            |
| ipb_core_clubs_fields                     |
| ipb_core_clubs_fieldvalues                |
| ipb_core_clubs_memberships                |
| ipb_core_clubs_node_map                   |
| ipb_core_contact_verify                   |
| ipb_core_content_featured                 |
| ipb_core_content_meta                     |
| ipb_core_deletion_log                     |
| ipb_core_dev                              |
| ipb_core_edit_history                     |
| ipb_core_editor_stored_replies            |
| ipb_core_email_templates                  |
| ipb_core_emoticons                        |
| ipb_core_error_logs                       |
| ipb_core_file_logs                        |
| ipb_core_file_storage                     |
| ipb_core_files                            |
| ipb_core_files_temp                       |
| ipb_core_follow                           |
| ipb_core_follow_count_cache               |
| ipb_core_geoip_cache                      |
| ipb_core_googleauth_used_codes            |
| ipb_core_group_promotions                 |
| ipb_core_groups                           |
| ipb_core_hooks                            |
| ipb_core_hooks_files                      |
| ipb_core_ignored_users                    |
| ipb_core_incoming_emails                  |
| ipb_core_inline_messages                  |
| ipb_core_ips_bulletins                    |
| ipb_core_item_markers                     |
| ipb_core_item_member_map                  |
| ipb_core_item_redirect                    |
| ipb_core_item_statistics_cache            |
| ipb_core_javascript                       |
| ipb_core_leaders                          |
| ipb_core_leaders_groups                   |
| ipb_core_like_cache                       |
| ipb_core_log                              |
| ipb_core_login_failures                   |
| ipb_core_login_handlers                   |
| ipb_core_login_links                      |
| ipb_core_login_methods                    |
| ipb_core_mail_error_logs                  |
| ipb_core_member_badges                    |
| ipb_core_member_history                   |
| ipb_core_member_privacy_actions           |
| ipb_core_member_ranks                     |
| ipb_core_member_recognize                 |
| ipb_core_member_status_replies            |
| ipb_core_member_status_updates            |
| ipb_core_members                          |
| ipb_core_members_feature_seen             |
| ipb_core_members_known_devices            |
| ipb_core_members_known_ip_addresses       |
| ipb_core_members_logins                   |
| ipb_core_members_warn_actions             |
| ipb_core_members_warn_logs                |
| ipb_core_members_warn_reasons             |
| ipb_core_menu                             |
| ipb_core_message_posts                    |
| ipb_core_message_topic_user_map           |
| ipb_core_message_topics                   |
| ipb_core_moderator_logs                   |
| ipb_core_moderators                       |
| ipb_core_modules                          |
| ipb_core_notification_defaults            |
| ipb_core_notification_preferences         |
| ipb_core_notifications                    |
| ipb_core_notifications_pwa_keys           |
| ipb_core_notifications_pwa_queue          |
| ipb_core_oauth_authorize_prompts          |
| ipb_core_oauth_clients                    |
| ipb_core_oauth_server_access_tokens       |
| ipb_core_oauth_server_authorization_codes |
| ipb_core_output_cache                     |
| ipb_core_permission_index                 |
| ipb_core_pfields_content                  |
| ipb_core_pfields_data                     |
| ipb_core_pfields_groups                   |
| ipb_core_plugins                          |
| ipb_core_points_log                       |
| ipb_core_polls                            |
| ipb_core_post_before_registering          |
| ipb_core_profanity_filters                |
| ipb_core_profile_completion               |
| ipb_core_profile_steps                    |
| ipb_core_question_and_answer              |
| ipb_core_queue                            |
| ipb_core_ratings                          |
| ipb_core_rc_author_notification_text      |
| ipb_core_rc_comments                      |
| ipb_core_rc_index                         |
| ipb_core_rc_reports                       |
| ipb_core_reactions                        |
| ipb_core_referral_banners                 |
| ipb_core_referrals                        |
| ipb_core_reputation_index                 |
| ipb_core_reputation_leaderboard_history   |
| ipb_core_reputation_levels                |
| ipb_core_rss_export                       |
| ipb_core_rss_import                       |
| ipb_core_rss_imported                     |
| ipb_core_s3_deletions                     |
| ipb_core_saved_charts                     |
| ipb_core_search_index                     |
| ipb_core_search_index_item_map            |
| ipb_core_search_index_tags                |
| ipb_core_security_answers                 |
| ipb_core_security_questions               |
| ipb_core_seo_meta                         |
| ipb_core_sessions                         |
| ipb_core_share_links                      |
| ipb_core_sitemap                          |
| ipb_core_social_promote                   |
| ipb_core_social_promote_content           |
| ipb_core_social_promote_sharers           |
| ipb_core_soft_delete_log                  |
| ipb_core_solved_index                     |
| ipb_core_spam_service_log                 |
| ipb_core_spam_whitelist                   |
| ipb_core_statistics                       |
| ipb_core_store                            |
| ipb_core_stream_subscriptions             |
| ipb_core_streams                          |
| ipb_core_sys_conf_settings                |
| ipb_core_sys_cp_sessions                  |
| ipb_core_sys_lang                         |
| ipb_core_sys_lang_words                   |
| ipb_core_sys_login                        |
| ipb_core_sys_settings_titles              |
| ipb_core_sys_social_group_members         |
| ipb_core_sys_social_groups                |
| ipb_core_tags                             |
| ipb_core_tags_cache                       |
| ipb_core_tags_perms                       |
| ipb_core_tasks                            |
| ipb_core_tasks_log                        |
| ipb_core_theme_conflict                   |
| ipb_core_theme_content_history            |
| ipb_core_theme_css                        |
| ipb_core_theme_resources                  |
| ipb_core_theme_settings_fields            |
| ipb_core_theme_settings_values            |
| ipb_core_theme_templates                  |
| ipb_core_themes                           |
| ipb_core_upgrade_history                  |
| ipb_core_validating                       |
| ipb_core_view_updates                     |
| ipb_core_voters                           |
| ipb_core_widget_areas                     |
| ipb_core_widget_trash                     |
| ipb_core_widgets                          |
| ipb_custom_bbcode                         |
| ipb_forums_answer_ratings                 |
| ipb_forums_archive_posts                  |
| ipb_forums_archive_rules                  |
| ipb_forums_forums                         |
| ipb_forums_posts                          |
| ipb_forums_question_ratings               |
| ipb_forums_topic_mmod                     |
| ipb_forums_topics                         |
| ipb_forums_view_method                    |
| ipb_nexus_alternate_contacts              |
| ipb_nexus_billing_agreements              |
| ipb_nexus_cart_uploads                    |
| ipb_nexus_coupons                         |
| ipb_nexus_customer_addresses              |
| ipb_nexus_customer_cards                  |
| ipb_nexus_customer_fields                 |
| ipb_nexus_customer_spend                  |
| ipb_nexus_customers                       |
| ipb_nexus_donate_goals                    |
| ipb_nexus_donate_logs                     |
| ipb_nexus_eom                             |
| ipb_nexus_fraud_rules                     |
| ipb_nexus_invoice_tracker                 |
| ipb_nexus_invoices                        |
| ipb_nexus_licensekeys                     |
| ipb_nexus_member_subscription_packages    |
| ipb_nexus_member_subscriptions            |
| ipb_nexus_notes                           |
| ipb_nexus_package_base_prices             |
| ipb_nexus_package_fields                  |
| ipb_nexus_package_filters                 |
| ipb_nexus_package_filters_map             |
| ipb_nexus_package_filters_values          |
| ipb_nexus_package_groups                  |
| ipb_nexus_package_images                  |
| ipb_nexus_packages                        |
| ipb_nexus_packages_ads                    |
| ipb_nexus_packages_products               |
| ipb_nexus_paymethods                      |
| ipb_nexus_payouts                         |
| ipb_nexus_product_options                 |
| ipb_nexus_purchases                       |
| ipb_nexus_referral_rules                  |
| ipb_nexus_reviews                         |
| ipb_nexus_ship_orders                     |
| ipb_nexus_shipping                        |
| ipb_nexus_support_default_content         |
| ipb_nexus_support_departments             |
| ipb_nexus_support_fields                  |
| ipb_nexus_support_notify                  |
| ipb_nexus_support_ratings                 |
| ipb_nexus_support_replies                 |
| ipb_nexus_support_request_log             |
| ipb_nexus_support_requests                |
| ipb_nexus_support_severities              |
| ipb_nexus_support_staff_dpt_order         |
| ipb_nexus_support_staff_preferences       |
| ipb_nexus_support_statuses                |
| ipb_nexus_support_stock_actions           |
| ipb_nexus_support_streams                 |
| ipb_nexus_support_tracker                 |
| ipb_nexus_support_views                   |
| ipb_nexus_tax                             |
| ipb_nexus_transactions                    |
| ipb_rc_reports_index                      |
| x_utf_ipb_convert_session                 |
| x_utf_ipb_convert_session_tables          |
+-------------------------------------------+