Мы успешно выполнили обновление несколько месяцев назад. Публикую наш опыт здесь для тех, кто может столкнуться с тем же вопросом в будущем.
Discourse частично поддерживает обновления без простоя, используя миграции после развертывания. Общий процесс, как мы его понимали, можно разделить на два этапа.
ЭТАП 1: Обновление до новой версии и выполнение безопасных миграций:
- Обновите все плагины и темы, чтобы они были совместимы с новой версией. (Это действительно довольно трудоемкая задача, в зависимости от вашей конфигурации).
- Сгенерируйте файл
web_only.ymlсо следующим содержимым:
version: <НОВАЯ_ВЕРСИЯ>
SKIP_POST_DEPLOYMENT_MIGRATIONS=1 - Выполните загрузку (
./launcher bootstrap web_only) - Перезапустите ваши серверы
ЭТАП 2: Выполнение миграций после развертывания (миграции высокого риска, такие как удаление столбцов и таблиц и т. д.). На данный момент этот этап должен быть безопасным, поскольку все ваши серверы работают с новой версией кода и не должны зависеть от удаляемых данных:
- Сгенерируйте файл
web_only.ymlсо следующим содержимым:
version: <НОВАЯ_ВЕРСИЯ>
SKIP_POST_DEPLOYMENT_MIGRATIONS=0 - Выполните загрузку (
./launcher bootstrap web_only) - Перезапустите ваши серверы
Сложности:
Мы решили выполнять ЭТАП 1 и ЭТАП 2 в разные даты, что привело к некоторым проблемам. Между версиями 2.1 и 2.3 в модели опросов произошло значительное рефакторинг. Похоже, что изначально большинство данных опросов хранилось в виде JSON-объекта в таблице post_custom_fields. К версии 2.3 они были перемещены в отдельную таблицу polls. Это потребовало миграции данных, которая была выполнена в рамках миграций после развертывания (ЭТАП 2).
Наша конкретная проблема заключалась в том, что сразу после обновления до версии 2.3 опросы, созданные до обновления, перестали работать, вероятно, потому, что код их рендеринга предполагал новую модель данных. Некоторые пользователи заметили это и попытались вручную обновить опросы через интерфейс, и в результате создали записи в новой таблице polls. Как мы позже с сожалением обнаружили, такие записи вызывали нарушение уникального ограничения в PostgreSQL во время процесса загрузки, что фактически приводило к его сбою.
Чтобы обойти эту проблему, мы решили применить патч, который пропускал конкретную миграцию опросов, если она уже существовала в базе данных. Это не было идеальным решением, так как можно было потерять данные из post_custom_fields, которые никогда не будут мигрированы для этих записей. Но в нашем случае это все же было приемлемым компромиссом, поскольку количество таких случаев было очень низким в нашей системе (мы наблюдали только 2 инстанса), и это позволило нам выполнить процесс загрузки. Теперь тестирование и применение патча подняло еще два вопроса:
-
Как протестировать изменения перед созданием PR?
Мы хотели протестировать наш код в тех же условиях, в которых он будет работать в реальности, то есть протестировать его в процессе загрузки. Это не так просто, как тестирование изменений кода во время выполнения, которое можно сделать, запустив автономное приложение Discourse локально. -
Как внедрить изменения в нашу систему?
Мы не хотели ждать, пока патч войдет в официальный релиз Discourse, что может занять много времени и фактически вынудит нас выполнить еще одно обновление. У нас уже были клиенты, жалующиеся на существующие опросы, и чем дольше мы ждали, тем выше были шансы, что клиенты вручную изменят опросы, усугубив проблемы целостности данных.
Поэтому мы нашли способ протестировать вносимые изменения, изменив источник репозитория, который использует скрипт загрузки. Это потребовало некоторых проб и ошибок, поскольку мы не очень хорошо разбираемся в pups и других инструментах, используемых в этом процессе. В итоге мы сделали что-то вроде этого.
Это позволило нам проверить, что наше исправление работает как задумано. Мы также смогли загрузить новый образ в продакшн из нашей собственной модифицированной версии Discourse, содержащей патч, не дожидаясь официального релиза Discourse.