Migrare un forum IPB 3.1 a Discourse

Ciao alla Community di Discourse,

Voglio condividere la mia esperienza sull’importazione di un forum IPB 3.1 in Discourse 2.1, sperando che ciò sia utile per altri.

Una breve sintesi sulla Community:

  • Argomento: Yii PHP Framework (discussioni e supporto relativi al codice)
  • Membri: ~26k
  • Argomenti: ~64k
  • Post: ~293k

L’importazione ha richiesto 27 ore e 46 minuti su una macchina con 16 GB di RAM e 4 core CPU.

Requisiti per l’importazione:

  • Mantenere i membri, ma pulire tutti gli account SPAM (~250k account, di cui ~26k rimangono dopo la pulizia)
  • Implementare l’SSO dal sito web (gli account utente non sono gestiti da Discourse)
  • Mantenere argomenti, post e categorie con i loro URL originali in modo che i risultati delle ricerche web funzionino ancora, così come altri link da piattaforme come Stackoverflow

Questo si basa su Migrating from Invision Power Board to Discourse - #23 by pfaffman, quindi grazie a @pfaffman per l’ottimo lavoro svolto sul programma di importazione.

Preparazione

Esportazione dei dati da IPB

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

Copia il dump SQL e gli upload sul nuovo server e mettili in /var/discourse/shared/standalone/.
Qui assumo una configurazione Docker semplice di Discourse.

Quale script utilizzare?

Ci sono due script di importazione, ipboard.rb e ipboard3.rb. Lo script ipboard3.rb sembra molto grezzo e non si adatta allo schema delle tabelle che abbiamo, quindi ho scelto ipboard.rb.

La versione corrente dello script di importazione ipboard.rb non gestisce bene gli allegati e non converte i tag del codice, il che è molto importante per noi dato che parliamo spesso di codice PHP. Quindi ho apportato le seguenti modifiche allo script:

Rendere disponibili gli allegati caricati

Lo script di importazione sostituisce gli allegati dei post con URL al file caricato.
Se intendi mantenere la tua istanza IPB online all’URL in cui si trovava prima, puoi semplicemente specificare l’URL (UPLOADS è una configurazione dello script di importazione, vedi sotto) alla directory degli upload e sei a posto:

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

Ma stiamo importando in Discourse per rimuovere completamente il vecchio forum, quindi dobbiamo mettere gli upload altrove. Se stai utilizzando un proxy nginx davanti a Discourse, puoi configurarlo per servire i file caricati da una directory sul server. Inserisci quanto segue nella parte server della configurazione di nginx:

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

E configura l’URL degli allegati (vedi sotto) in questo modo:

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

Configurazione di MySQL nel container di Discourse

Avvia una shell bash nel container dell’app Discourse:

docker exec -it app bash

Nel container, installa MySQL e importa il database:

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

Quando ho provato la prima importazione per testare lo script, è durata diversi giorni per importare 200k utenti, di cui sapevamo che una grande quantità erano account SPAM, quindi abbiamo creato alcune query SQL per eliminare gli account che non avevano mai pubblicato nulla:

Nota che useremo SSO, quindi gli utenti eliminati verranno ricreati quando accederanno.
Se non userai SSO, i tuoi criteri per eliminare gli utenti potrebbero essere diversi.
Puoi importare i tuoi dati senza pulirli.

mysql -uroot -p
# poi applica le query di pulizia

Successivamente dobbiamo installare le dipendenze per lo script di importazione:

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

Per consentire l’accesso al database Postgres di Discourse, sostituisci peer con trust in /etc/postgresql/10/main/pg_hba.conf. Nota che 10 rappresenta la versione di postgres; se il file non esiste nella tua configurazione, sostituisci 10 con la versione di postgres che stai eseguendo attualmente.
Riavvia Postgres per caricare le modifiche: service postgresql restart

Importazione

Prepara gli avatar e i file caricati:

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

Esegui lo script di importazione:

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

Assicurati di regolare l’URL UPLOADS come discusso sopra, poiché gli upload saranno inclusi nei post come link al file di upload originale.

Pulizia

Se tutto è andato bene, esegui la pulizia con service mysql stop, apt-get purge mysql-server, rm -rf /var/lib/mysql

Configurazione della reindirizzazione degli URL

Per mantenere intatti gli URL esistenti al forum, lo script di importazione crea permalink per ogni argomento che riflettono l’URL di argomenti e categorie in IPB.
Tuttavia, questi permalink non coprono i link a post specifici in un argomento o pagine diverse.
Affinché questi URL funzionino correttamente, devi configurare alcune regole di riscrittura degli URL; ci sono 3 opzioni:

  • Utilizzare l’impostazione permalink normalizations in Discourse per rimuovere parti non necessarie dagli URL
  • Regole di riscrittura in nginx, se hai un proxy nginx davanti a Discourse
  • Se il vecchio forum era su un URL/Host diverso rispetto a Discourse, puoi utilizzare uno script personalizzato per riscrivere gli URL (questo è ciò che ho fatto)

Ecco il codice PHP che usiamo per la reindirizzazione degli URL:

Risorse correlate

18 Mi Piace

Ciao,

scusa per aver ripreso questo vecchio argomento, ma sto pianificando anch’io la migrazione da IPB (v3.4) a Discourse e sto seguendo questa guida. Ho deciso quindi di rispondere direttamente qui invece di creare un nuovo argomento.

Il pacchetto mysql non è più incluso nella distribuzione, quindi ho seguito questa guida
essenzialmente:

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

ma poi ricevo il seguente errore
mysql: servizio non riconosciuto

avete qualche idea su come avviare mysql?

Grazie

Ci sono stati errori quando hai eseguito i comandi che avrebbero dovuto installarlo? Ti consiglio una ricerca su Google.

Inoltre, potresti voler usare lo script ipb che fa parte di Discourse piuttosto che quello a cui si fa riferimento nell’OP.

Ci sono aggiornamenti per questo script perché non funzionerà con IPB 4x ed è anche incompatibile con Discourse stesso poiché la struttura delle tabelle è cambiata e lo script rimane com’è

1 Mi Piace

Sto ora eseguendo un’importazione di ipboard. Ho dovuto rimuovere alcune tabelle e righe da alcune delle query. Sembra che abbiano molte configurazioni di tabelle diverse.

Anche ottenere i post grezzi di ipb in markdown è complicato.

Se hai un budget, puoi contattarmi. Potrei essere in grado di darti il codice che ho ottenuto per l’importazione che sto facendo ora, ma probabilmente richiederà lavoro per la tua particolare configurazione.

2 Mi Piace

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