Я заметил, что задача rake assets:precompile требует подключения к базе данных: это означает, что её можно выполнить только во время «запуска» (после развёртывания), а не во время «сборки» (при создании образа контейнера). Поскольку выполнение этой задачи занимает много времени, это может быть неудобно.
Не будучи разработчиком Ruby/Rails, я провёл исследование и выяснил, что такое поведение можно отключить вплоть до версии Rails 4, а после этого разработчики стали прибегать к различным хитростям (например, использование нулевого подключения к базе данных). Последний подход, разумеется, требует глубокого понимания приложения, чтобы ничего не сломать.
В поисках лучшего решения я нашёл этот коммит, который кажется похожим по духу. Поэтому у меня следующие вопросы:
Разработчики уже работают над этим вопросом или существуют технические причины, по которым это невозможно?
Если некоторые части задачи действительно требуют подключения к базе данных, будет ли целесообразно разделить задачу на две (или более), чтобы часть работы (например, компиляция локалей, минификация JS и CSS) выполнялась на этапе сборки?
Существует ли известное обходное решение на данный момент (например, «нулевая база данных», упомянутая выше)?
Мы храним темы в базе данных (они редактируются в административном интерфейсе), поэтому CSS находится внутри PostgreSQL, и для возможности предварительной компиляции этих стилей необходимо подключение к базе данных во время сборки.
Можно ли реализовать отдельную сборку локалей (которую можно запускать на этапе сборки)?
Также я могу представить, что в некоторых средах (как минимум в моей) нежелательно менять темы: возможно ли в таком случае предусмотреть альтернативное хранилище для CSS?
Мы обсуждали идею переключателя, который отключал бы весь интерфейс кастомизации, позволяя компилировать CSS-файлы на этапе сборки и загружать их в объектное хранилище во время сборки (то есть так же, как это делается для ядра JS и плагинов).
Однако это очень узкоспециализированный случай, который мог бы заинтересовать только корпоративные развертывания, при этом не принося никакой пользы 99% сообществ в интернете. Поэтому это не входит в наш план работ, и будет довольно сложно обосновать выполнение этой задачи вместо разработки новых функций или работы над производительностью.
Можете ли вы рассказать подробнее о вашей среде и сценарии использования?
Хорошо знать, что эта идея уже обсуждалась. Я понимаю, что объем работы, необходимый для внесения изменений, вероятно, слишком велик, чтобы это было оправдано.
В моем случае Discourse будет связан с уже существующим веб-сайтом, поэтому будет использоваться фиксированная пользовательская тема, соответствующая теме сайта: динамически менять её не имело бы смысла.
О, ну, когда я собираю образ, я работаю на своём ноутбуке для разработки. Затем образ выгружается в репозиторий, а финальная система (VPS на DigitalOcean) забирает его оттуда.
База данных находится в томе на VPS, поэтому её нельзя обновить с моего ноутбука: для этого мне пришлось бы остановить Discourse, синхронизировать базу данных с ноутбуком через rsync, собрать и выгрузить образ, а затем снова запустить Discourse…
Значит, вы запускаете базу данных и приложение в одном Droplet?
В этом случае следование нашему официальному руководству по установке, которое предполагает размещение приложения и базы данных в одном Droplet, позволит вам получить полностью функциональный сайт. Его можно обновлять через веб-интерфейс, а при необходимости — через командную строку с полной пересборкой образа.
Если под этим вы имеете в виду «напрямую на хосте», то нет. Они работают в контейнере, а именно в контейнере podman. В идеале я бы разделил контейнер на несколько (один для Discourse, один для PostgreSQL, один для Redis…), но это связано с вопросом, который мы обсуждаем, поэтому я всё ещё не уверен в правильном курсе действий.
Кажется мне небезопасным. Я обычно тестирую контейнеры в своей среде разработки перед развертыванием в продакшн. Кроме того, в идеале контейнеры должны быть доступны только для чтения.
Вы можете разделить эти контейнеры, а затем запустить процесс инициализации образа на другом, кратковременном дроплете. Поскольку дроплеты оплачиваются почасово, это будет недорого. Вы даже можете использовать частную сеть дроплетов между хостом контейнера базы данных и хостом контейнера «сборки».
Ха-ха, спасибо за идею, но это начинает усложняться. Кроме того, это не решит проблему, потому что нам всё равно нужно остановить Discourse и дождаться процесса загрузки, иначе могут возникнуть несогласованные данные.
Похоже, нам придётся смириться с длительным простоем (5–6 минут на миграцию и прекомпиляцию) при обновлении. Тем не менее, я был бы признателен, если бы вы создали задачу низкого приоритета в трекере, возможно, со ссылкой на эту тему.
Это должно занять всего «несколько секунд» вместо 5–6 минут, но для этого требуются отдельные контейнеры данных и веб-сервера. Всё зависит от того, что для вас важнее.
Кроме того, согласно бенчмаркам, перестройка на быстром сервере должна занимать около 3 минут.
Хорошо, спасибо. В таком случае я точно разделю контейнеры, что в любом случае является более правильной архитектурой.
Однако я не понимаю, в чём здесь разница? Если я не ошибаюсь, все контейнеры будут использовать все процессоры хоста (если не настроено иначе), поэтому процессы должны выполняться параллельно в обоих случаях. Я что-то упускаю?
Ваш старый контейнер будет работать, пока новый проходит процесс инициализации. Затем вы сможете быстро отключить старый и запустить новый, что сократит время простоя.