Предварительная оценка миграции для крупного форума на Drupal 7

Всем привет! Я владею и администрирую, как мне кажется, один из крупнейших форумов на базе Drupal в интернете — почти 2 миллиона сообщений. Drupal 7 уходит в прошлое, а Drupal 8/9 всё больше превращается в фреймворк для веб-программистов, а не в готовую к использованию систему управления контентом. Новые версии Drupal просто не предлагают сторонние модули, необходимые для поддержания базовых функций моего форума. А благодаря «прелестям» PHP и множеству других особенностей Drupal, миграция на новую версию была бы столь же мучительной, как переход на совершенно другую платформу. Поэтому мне придётся решиться и мигрировать на что-то другое. Я почти уверен, что это будет Discourse, из-за уникальной особенности стиля моего сообщества: я единственный модератор, и это не моя основная работа. Поэтому за годы я использовал гибкие фреймворки Rules и Flag в Drupal, чтобы создать фрагментарную систему модерации сообщества для борьбы со спамом и оскорбительными сообщениями: автоматическое удаление постов и/или блокировка учётных записей пользователей при достижении определённых порогов, с учётом новизны пользователя, количества пользователей, отметивших пост, а также новизны и недавней активности отметок тех, кто ставит отметки. Другими словами, это почти в точности то, что реализовано в Discourse. Я очень рад видеть, что Discourse оценил важность модерации сообщества и внедрил столь комплексную и продуманную систему «из коробки». Drupal 7 был и остаётся единственной CMS, достаточно гибкой, чтобы позволить такую кастомную функциональность без опыта разработки, которого у меня нет. Так что похоже, я перехожу на Discourse. Однако у меня есть некоторые опасения.

  1. Система модерации сообщества: Наш форум сейчас тестирует установочную версию Discourse. Я впечатлён тем, насколько комплексной и продуманной является вся система. Но сообщество заметило некоторые особенности:
    • Мне очень не нравится, что автоматически удалённые посты скрываются за пунктом «Просмотреть проигнорированный контент». Если пост настолько плох, что был удалён сообществом, он либо крайне оскорбителен, либо чистый спам, и я не хочу, чтобы посетители или пользователи даже имели возможность его просматривать. Это особенно проблематично в случае тем, которые являются спамом или имеют оскорбительный заголовок. Не увидят ли поисковые роботы скрытый спам-контент? Можно ли настроить время без вмешательства пользователя, после которого автоматически скрытый спам-пост будет полностью удалён из публичного доступа? А как насчёт тем и постов, отмеченных сообществом как неуместные?
    • Я прочитал здесь, что «Примечание: все упомянутые выше значения являются настройками по умолчанию. Их можно изменить администраторами в настройках сайта» относительно порогов, ведущих к удалению постов и/или блокировке пользователей, но я не вижу таких детальных настроек в моём тестовом экземпляре Discourse. Я нашёл только «скрытие чувствительности постов» и «чувствительность блокировки новых пользователей», но не понимаю, к чему конкретно относится эта чувствительность.
    • Я хотел бы удалить причину «не по теме» для отметки поста. Наше сообщество в этом плане очень расслаблено, и у нас культура форума, где посты не по теме очень распространены и принимаются. Обновление: Похоже, что это может сработать.
  2. Миграция личных сообщений: На текущем форуме почти миллион потоков личных сообщений с использованием модуля privatemsg для Drupal 7, и скрипт миграции Drupal → Discourse не поддерживает это. Это кажется серьёзным упущением, потому что, несмотря на то, что это сторонний модуль (в типичной манере Drupal), он фактически является де-факто функциональностью личных сообщений, которую используют администраторы Drupal 7.
  3. Конвертация формата постов: К сожалению, текущий форум использует смесь чистого HTML и постов в формате Textile. Я понимаю, что скрипт миграции может обрабатывать чистый HTML (поправьте меня, если я ошибаюсь), но не Textile. Если возможно, я хотел бы конвертировать посты в формате Textile в HTML или Markdown, что будет проще. Мне сказали, что Pandoc можно подключить к скрипту миграции, но это значительно увеличит время миграции. Я искал модули Drupal для конвертации формата существующих постов, но нашёл только этот, который не поддерживает пакетную обработку для огромного количества постов и не поддерживает парадигму «комментариев» Drupal, которая составляет подавляющее большинство «постов», требующих конвертации. Поэтому я подумал просто сделать какой-то офлайн-поиск и замену в дампе базы данных с помощью sed, аналогично тому, что описано здесь. Предложения или решения будут приветствоваться. Я опытный пользователь Linux и время от времени работал с регулярными выражениями, но всё ещё не очень хорошо в этом. Редактирование: Это интересный вариант для поиска и замены после того, как сырые данные попадут в Discourse.
  4. Реклама: Я очень рад видеть, что плагин Ad для Discourse значительно созрел с момента моего последнего взгляда на него. Я понимаю, что встроенная реклама позволит мне размещать баннеры с изображениями в определённых местах с целевой ссылкой при клике, и что если несколько объявлений назначены одному и тому же месту, они будут выбираться случайно, верно? Однако я не знаю, как справиться с мобильным парадигмой. На моём текущем форуме есть один верхний горизонтальный баннер и три вертикальных баннера в левой боковой панели, что невозможно для мобильных пользователей в адаптивном интерфейсе Discourse. Редактирование: Возможно, придётся модифицировать плагин Ad под свои нужды, платное предложение здесь.
  5. Постоянные ссылки (пермалинки): В схеме URL Drupal есть два основных компонента: /node/XXXXXXX и ссылки на конкретные комментарии внутри этих узлов /comment/YYYYYYY#comment-YYYYYYY (YYYYYYY одинаково в обоих случаях). Скрипт миграции Drupal 7 → Discourse автоматически сохранит эти ссылки, чтобы ссылки в постах на другие темы или посты продолжали работать и сохраняли SEO? А что насчёт файла sitemap.xml для поисковых систем?
  6. Пакетная обработка: Будет ли миграция выполняться пакетами? Что произойдёт, если возникнет ошибка: после её исправления продолжится ли процесс или потребуется начинать с самого начала?
  7. Пользователи со старыми устройствами Apple: Я, конечно, понимаю опасности использования устаревших браузеров. Для Windows и старых устройств Android почти всегда есть способ установить современный браузер, совместимый с Discourse. Но меня беспокоит один из моих пользователей, который утверждает, что у него Mac 2015 года, который не получает обновлений и не позволяет установить ничего, кроме старой версии Safari, которая показывает ему уведомления об устаревании при работе с Discourse. Я очень мало знаю об устройствах Apple, кроме того факта, что они гораздо более закрыты. Действительно ли так сложно установить другие современные браузеры на них?
  8. Хранение изображений/загрузок: Мои пользователи и я любим удобство загрузки изображений в Discourse, но я немного беспокоюсь о месте для хранения и затратах. Лучшим вариантом в будущем, вероятно, будет подключение сетевого тома к VPS при необходимости. Если я изначально настрою Discourse с расположением загрузок по умолчанию, вызовет ли это проблемы при перемещении на другой том позже?
  9. Резервное копирование:
    • Я хотел бы иметь систему дифференциальных, а лучше дедуплицированных резервных копий. В настоящее время я использую Duplicity с Amazon S3 для моего форума на Drupal, и затраты невероятно низкие для очень долгой истории версий. Знает ли кто-нибудь, как скоро после создания архива S3 правило может перевести его в Glacier?
    • Позволяет ли интерфейс резервного копирования Discourse удалять архивы в Amazon S3? Я знаю, что это немного экстремально, но я хотел бы отключить эту функцию, потому что я настроил свои бакеты S3 только с правами PUT, GET и LIST, чтобы предотвратить удаление удалённых резервных копий хакером на скомпрометированной системе. Затем срабатывает правило жизненного цикла S3, и серверная часть удаляет более старые архивы после определённого периода времени.
  10. Плагин Stop Forum Spam: Я не хочу использовать Akismet, но у меня всегда были хорошие результаты с StopForumSpam.com для предотвращения создания множества учётных записей спамеров. Знает ли кто-нибудь, есть ли в плагине для Discourse настраиваемые пороги для количества совпадений имени пользователя, IP-адреса или адреса электронной почты в базе данных, при которых он будет отклонён? Редактирование: Нет, не имеет. Запрос здесь. Также, к сожалению, он не вмешивается, чтобы фактически предотвратить создание учётной записи, если у них достаточно совпадений в базе данных SFS, как это происходит в Drupal.

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

Я только что наткнулся на это:

применить набор преобразований на основе регулярных выражений, таких как замена тегов BBCode на Markdown

Последнее обновление было в 2016 году, не уверен, что это всё ещё актуальный вариант.


Это всё ещё актуально? В скрипте импортера для Drupal я вижу код вроде:

 create_posts(results, total: total_count, offset: offset) do |row|
        topic_mapping = topic_lookup_from_imported_post_id("nid:#{row['nid']}")
 def create_permalinks
    puts '', 'создание постоянных ссылок...'

    Topic.listable_topics.find_each do |topic|
      begin
        tcf = topic.custom_fields
        if tcf && tcf['import_id']
          node_id = tcf['import_id'][/nid:(\d+)/, 1]
          slug = "/topic/#{node_id}"
          Permalink.create(url: slug, topic_id: topic.id)
        end

Скрипт обычно загружает по 1000 постов за раз.

Он отслеживает обработанные данные, поэтому при повторных запусках уже обработанные данные пропускаются. В скриптах, которые я дорабатывал, я также добавлял настройку import_after, что ещё больше ускоряет последующие запуски, загружая только свежие данные (это также полезно при тестировании на небольшом подмножестве данных).

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

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

О, это очень хороший момент. Теперь, когда я об этом думаю, я все равно буду платить за хранение загрузок в S3, независимо от того, загружаются ли они напрямую (и только) в S3 или находятся внутри нескольких tar-архивов из резервной копии Discourse.

А как насчет использования ведра без разрешений на удаление для резервных копий Discourse?

Но если они находятся в S3, то у вас есть только одна копия.

Я предполагаю, что это сработает, если у Discourse нет прав на удаление, хотя я не уверен.

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

Да, вы можете включить управление версиями, чтобы файлы не удалялись при их пометке как удалённые. Если для вас не имеет значения, сколько места вы оплачиваете, вы можете это сделать. Когда Discourse удаляет файл, потому что он больше не используется, он временно перемещает его в папку-тумблстон перед окончательным удалением. Я рекомендую доверять Discourse управление файлами. Я не знаю, приведёт ли запрет на доступ к удалению к каким-либо сбоям.

Вы можете разместить резервные копии в отдельном хранилище (bucket) с другими разрешениями (но теми же учётными данными), если хотите.

Вопрос к @pfaffman или любому другому, кто загружает файлы на S3: я понимаю, что это зависит от множества факторов, но у вас есть хоть какая-то анекдотическая информация о расходах на пропускную способность и запросы к S3 для форума среднего и крупного размера, где все загрузки хранятся на S3? Большое спасибо!

Небольшое обновление: в итоге я решил хранить загрузки локально. У меня пока достаточно локального хранилища, и при необходимости я смогу расширить его дополнительными томами. Просто не хочу сталкиваться со сложностью и расходами на CDN, непредсказуемыми тарифами объектного хранилища и, что важнее всего, с затратами на передачу данных при обслуживании изображений на живом сайте. Далее я настрою автоматическое резервное копирование в S3 на Backblaze B2, включая загрузки, и включу опцию s3 disable cleanup. Тарифы Backblaze настолько низкие, что хранение нескольких недель ежедневных резервных копий, даже с дублированием загрузок, не должно стать проблемой. Оказалось, что в Backblaze B2 есть два очень простых варианта настройки бакетов, которые мне идеально подходят: 1) автоматические правила жизненного цикла для удаления файлов через X дней и 2) запрет на удаление или изменение файлов в течение N дней (чтобы исключить малую вероятность взлома сервера и использования злоумышленником сохранённых учётных данных для удаления моих удалённых резервных копий). Я протестировал это, и всё работает как надо: я попытался удалить архив резервной копии через интерфейс Discourse, но так как Backblaze запрещал удаление, ничего не произошло.

Просто для уточнения для меня и для других: верно ли, что можно автоматически резервировать загрузки с локального хранилища в S3, если включена опция backup with uploads (по умолчанию)?

Да. По умолчанию локальные загрузки включаются в файл резервной копии.