Подскажите, пожалуйста, как создать образ Docker для Discourse с набором встроенных плагинов, вместо их установки через интерфейс?
Контекст: мы хотим использовать последнюю сборку Discourse, то есть discourse:stable. Судя по тому, что я прочитал в руководстве по установке и другой документации, мы можем использовать этот образ как базовый в собственном Dockerfile и выполнить что-то вроде:
RUN cd /var/www/discourse/plugins && \
git clone https://github.com/discourse/discourse-chat-integration.git
Это добавит плагин discourse-chat-integration в сборку. Затем во время выполнения мы можем передать все необходимые переменные окружения, например DISCOURSE_HOSTNAME, DISCOURSE_SMTP_DOMAIN, DISCOURSE_DB_HOST и т. д., вместо того чтобы прописывать их напрямую в файле app.yml.
Будем очень признательны за любые советы по этому вопросу.
Плагины нельзя установить через интерфейс. Их добавляют в файл YML. Если вы используете какой-то ещё не поддерживаемый контейнер, который вы не создавали самостоятельно с помощью утилиты launcher, то вы можете сделать именно то, что предлагаете.
Но этот плагин уже входит в основную сборку (хотя, возможно, ещё не в стабильную версию?).
Они на самом деле не зашиты жёстко в файл YML. Файл YML используется для сборки и запуска контейнера. Вы можете собрать его и затем запустить самостоятельно любым удобным способом. Вы можете использовать команду ./launcher start-cmd container-name (или что-то подобное; вы можете проверить в утилите launcher, не ошибся ли я).
Так что, я думаю, вам нужно продолжать использовать утилиту launcher, добавить плагин, выполнить ./launcher bootstrap app для сборки контейнера, а затем запустить его любым способом. Вы даже можете выгрузить его в репозиторий, откуда сможете запускать с другой машины.
Итак, наша цель — запустить Discourse в нашем кластере Kubernetes и иметь возможность собирать образ в рамках нашего CI/CD-процесса, отсюда и кастомный Dockerfile. Все переменные окружения затем передаются работающему поду через ConfigMap и/или Secret. Я понимаю, что это не поддерживаемый способ установки, но я пытаюсь хотя бы использовать поддерживаемый метод сборки образа Discourse для конкретной версии, чтобы мы могли контролировать момент обновления.
Изучив существующий скрипт launcher и файл samples/web_only.yml, я полагаю, что могу закомментировать секции volumes и links, так как в Kubernetes это будет реализовано через Persistent Volume и монтирование. Затем мы добавим фиксированные значения переменных окружения в web_only.yml, соберём контейнер с помощью команды bootstrap, а затем скопируем полученный образ в наш собственный репозиторий.
Что касается версии Discourse, мы можем отслеживать появление новых релизов в Docker Hub и затем обновлять значение base_image в файле web.template.yml.
Правильно ли я понимаю?
Ещё один вопрос: в web.template.yml выполняется команда db:migrate, но на момент запуска bootstrap у нас нет подключения к базе данных. Я пробовал использовать флаг --skip-tags, но, похоже, он больше не работает. Можно ли просто удалить эту команду из шаблона, так как она будет выполнена в init-контейнере при запуске пода?
Возможно, но контейнеру обычно нужно подключаться к какой-либо базе данных для сборки. Это не обязательно должна быть основная база данных (но в таком случае вам потребуется выполнить миграцию базы данных и предкомпиляцию ассетов в вашем пайплайне).
Возможно, вы смешиваете проблему обновлений самой версии Discourse с обновлениями ресурсов в базовом контейнере.
Мне удалось собрать контейнер без хука db:migrate — пока не уверен, что это сработает, так как я ещё не тестировал это. Это в списке задач
Что касается значения base_image — я предполагаю, что оно меняется при выпуске нового образа Docker, поэтому думаю, просто возьму то, что есть в ветке main, так как именно это вызывается в скрипте запуска.
Спасибо, Джей. Наконец-то моя сборка заработала, точнее, под запустился Я изменил процесс сборки CI/CD, добавив db:migrate с использованием временной базы данных.
Всегда ли необходимо выполнять db:migrate при запуске, если моя сборка образа производится против тестовой базы данных/Redis? Мой текущий подход заключается в том, что db:migrate и precompile выполняются в initContainer внутри моего пода.
Образ discourse/discourse был бы идеален, если он скоро станет готовым для продакшена.
Если вы заинтересованы в обновлениях без простоя, используйте SKIP_POST_DEPLOYMENT_MIGRATIONS, а после остановки старых подов выполните миграцию повторно с помощью команды вроде rake db:ensure_post_migrations db:migrate.
В данный момент я устанавливаю несколько переменных окружения при развёртывании, например DISCOURSE_BACKUP_LOCATION=s3. Насколько я понимаю, Discourse будет использовать это значение вместо того, которое установлено через интерфейс и, следовательно, хранится в таблице site_settings. Так ли это? Если да, существуют ли какие-либо инструменты или скрипты, которые позволили бы мне проверить, какие переменные окружения установлены, и определить их эквиваленты в настройках сайта?
Почему? Я планирую миграцию работающего экземпляра Discourse и, чтобы минимизировать риски, хотел пока не устанавливать переменные окружения на случай, если я что-то упустил в новом экземпляре, что могло бы негативно повлиять на его работу. Я думал, что могу проверить, что установлено в текущем экземпляре, создать соответствующие настройки в таблице, сделать резервную копию и восстановить её в новом экземпляре, а затем по одной перенести настройки в переменные окружения.
Логично? Возможно, нет, но мне казалось, что это наиболее здравый подход на случай, если переменная окружения в работающем экземпляре отличается или не поддерживается в новом экземпляре (работающий = старая версия Discourse, новый = последняя версия Discourse).
Отчасти. Они переопределяют то, что находится в базе данных. Эти значения записываются в файл /var/www/discourse/config/discourse.conf или что-то очень похожее на него.