Migrer un forum IPB 3.1 vers Discourse

Bonjour à la communauté Discourse,

Je souhaite partager mon expérience d’importation d’un forum IPB 3.1 vers Discourse 2.1, en espérant que cela sera utile à d’autres.

Un bref résumé sur la communauté :

  • Sujet : Framework PHP Yii (discussions et support liés au code)
  • Membres : ~26k
  • Sujets : ~64k
  • Messages : ~293k

L’importation a pris 27h 46min sur une machine avec 16 Go de RAM et 4 cœurs CPU.

Exigences de l’importation :

  • Conserver les membres, mais nettoyer tous les comptes SPAM (~250k comptes dont ~26k restent après le nettoyage)
  • Implémenter le SSO depuis le site web (les comptes utilisateurs ne sont pas gérés par Discourse)
  • Conserver les sujets, les messages et les catégories avec leurs URLs d’origine afin que les résultats des moteurs de recherche fonctionnent toujours, ainsi que les autres liens provenant de plateformes comme Stackoverflow

Ceci est basé sur Migrating from Invision Power Board to Discourse - #23 by pfaffman, merci à @pfaffman pour le travail accompli sur l’importateur.

Préparation

Exportation des données depuis IPB

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

Copiez le dump SQL et les fichiers uploadés vers le nouveau serveur et placez-les dans /var/discourse/shared/standalone/.
Je suppose ici une configuration Docker simple de Discourse.

Quel script utiliser ?

Il existe deux scripts d’importation, ipboard.rb et ipboard3.rb. Le script ipboard3.rb semble très brut et ne correspond pas non plus au schéma de table que nous avons, j’ai donc opté pour ipboard.rb.

La version actuelle du script d’importation ipboard.rb ne gère pas bien les pièces jointes et ne convertit pas non plus les balises de code, ce qui est très important pour nous car nous parlons beaucoup de code PHP. J’ai donc apporté les modifications suivantes au script :

Rendre les pièces jointes téléchargées disponibles

Le script d’importation remplace les pièces jointes des messages par des URLs vers le fichier téléchargé.
Si vous conservez votre instance IPB en ligne à l’URL où elle se trouvait auparavant, vous pouvez simplement spécifier l’URL (UPLOADS est une configuration du script d’importation, voir ci-dessous) vers le répertoire des uploads et c’est tout :

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

Mais nous importons vers Discourse pour supprimer complètement l’ancien forum, nous devons donc placer les uploads ailleurs. Si vous utilisez un proxy nginx devant Discourse, vous pouvez le configurer pour servir les fichiers téléchargés depuis un répertoire sur le serveur. Ajoutez ce qui suit dans la partie server de la configuration nginx :

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

Et configurez l’URL des pièces jointes (voir ci-dessous) comme ceci :

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

Configuration de MySQL dans le conteneur Discourse

Démarrer un shell bash dans le conteneur de l’application Discourse :

docker exec -it app bash

Dans le conteneur, installez MySQL et importez la base de données :

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

Lorsque j’ai tenté la première importation pour tester le script, cela a pris plusieurs jours pour importer 200k utilisateurs, dont nous savions qu’une grande partie étaient des comptes SPAM. Nous avons donc créé quelques requêtes SQL pour supprimer les comptes qui n’avaient jamais publié quoi que ce soit :

Notez que nous allons utiliser le SSO, donc les utilisateurs supprimés seront recréés lors de leur connexion.
Si vous n’allez pas utiliser le SSO, vos critères de suppression des utilisateurs pourraient être différents.
Vous pouvez importer vos données sans les nettoyer.

mysql -uroot -p
# puis appliquez les requêtes de nettoyage

Ensuite, nous devons installer les dépendances pour le script d’importation :

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

Pour autoriser l’accès à la base de données Postgres de Discourse, remplacez peer par trust dans /etc/postgresql/10/main/pg_hba.conf. Notez que 10 représente la version de postgres ; si le fichier n’existe pas dans votre configuration, remplacez 10 par la version de postgres que vous exécutez actuellement.
Redémarrez Postgres pour charger les modifications : service postgresql restart

Importation

Préparez les avatars et les fichiers téléchargés :

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

Exécutez le script d’importation :

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

Assurez-vous d’ajuster l’URL UPLOADS comme discuté ci-dessus, car les uploads seront inclus dans les messages sous forme de liens vers le fichier d’origine téléchargé.

Nettoyage

Si tout s’est bien passé, nettoyez avec service mysql stop, apt-get purge mysql-server, rm -rf /var/lib/mysql

Configuration de la redirection d’URL

Pour conserver les URLs existantes vers le forum intactes, le script d’importation crée des permaliens pour chaque sujet qui reflètent l’URL des sujets et des catégories dans IPB.
Cependant, ces permaliens ne couvrent pas les liens vers des messages spécifiques dans un sujet ou des pages différentes.
Pour que ces URLs fonctionnent correctement, vous devez configurer certaines règles de réécriture d’URL ; il existe 3 options :

  • Utiliser le paramètre permalink normalizations dans Discourse pour supprimer les parties inutiles des URLs
  • Règles de réécriture dans nginx, si vous avez un proxy nginx devant Discourse
  • Si l’ancien forum se trouvait à une URL/hôte différent de Discourse, vous pouvez avoir un script personnalisé pour réécrire les URLs (c’est ce que j’ai fait)

Voici le code PHP que nous utilisons pour la redirection d’URL :

Ressources connexes

18 « J'aime »

Hello,

sorry to bump this old topic, but i’m also planning to migrate from IPB (v3.4) to Discourse and I’m following this howto. So i figured out I will directly reply in this topic instead of creating a new one.

mysql package is no longer in the distribution, so I followed this guide
basically:

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

but then i get below error
mysql: unrecognized service

any idea how I can start mysql ?

Thank you

Y a-t-il eu des erreurs lorsque vous avez exécuté les commandes qui auraient dû l’installer ? Je recommande une recherche Google.

De plus, vous voudrez peut-être utiliser le script ipb qui fait partie de Discourse plutôt que celui référencé dans le OP.

Y a-t-il une mise à jour pour ce script car il ne fonctionnera pas avec IPB 4x et il n’est pas non plus compatible avec Discourse lui-même car la structure des tables a changé et le script est resté tel quel.

1 « J'aime »

J’effectue actuellement une importation ipboard. J’ai dû supprimer certaines tables et lignes de certaines requêtes. Il semble qu’elles aient de nombreuses configurations de tables différentes.

Obtenir les publications brutes d’ipb en markdown est également délicat.

Si vous avez un budget, vous pouvez me contacter. Je pourrais peut-être vous donner le code que j’ai obtenu pour l’importation que je fais actuellement, mais il nécessitera probablement des ajustements pour votre configuration particulière.

2 « J'aime »

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