Сборщик образов Discourse для конвейеров Gitlab CI/CD

Привет!

Мы создали репозиторий под названием RPS Discourse Image Builder, который используется для создания образа OCI для Discourse. Думаю, это может быть полезно некоторым из тех, кто здесь находится. Мы сделали это в основном для того, чтобы не ждать развёртывания Discourse, которое занимает много времени, и чтобы иметь возможность надёжно фиксировать версию Discourse.

Мы написали скрипт, который использует репозиторий discourse_docker для создания образа с стабильной версией максимально универсальным способом.

Также существует файл docker compose, который поднимает необходимые для сборки базы данных и образ Discourse для тестирования и запускает их для локальной разработки. Это можно запустить на GitLab runner с исполнителем shell, но для этого нужна система с версией docker-compose, поддерживающей профили.

Подход

Скрипт сборки должен запускаться в наших пайплайнах CI/CD, чтобы мы могли легко обновлять версию, и дальнейшие настройки производились в других репозиториях с Dockerfile, основанными на образе, созданном этим репозиторием.

Предыстория

Discourse — очень хороший программный продукт, но его не очень легко развёртывать и фиксировать по версии. Этот репозиторий используется для создания Docker-образа, который можно использовать для развёртывания Discourse.

Проблема в том, что у Discourse очень уникальный способ создания своих Docker-образов. Разработчики Discourse ожидают, что вы будете собирать образ на целевой машине с использованием их репозитория discourse_docker.

На форуме велись длительные обсуждения по этому поводу. Если кратко: ведущие разработчики Discourse отказываются поддерживать публичный Docker-образ, который можно использовать для развёртывания Discourse. Они хотят сохранить репозиторий discourse_docker как единственный официальный способ развёртывания Discourse.

Основные недостатки такого подхода:

  • По нашему опыту, невозможно надёжно фиксировать версию Discourse.
  • Сборка образа занимает много времени, и когда образ собран, сервис недоступен. Кроме того, у Discourse самый длинный цикл итераций DevOps среди всех поддерживаемых нами сервисов.
  • Базы данных управляются иначе, чем в обычных проектах на основе Docker.
  • Официальный сценарий развёртывания Discourse несовместим с рабочими процессами и развёртываниями, основанными на OCI, такими как Kubernetes или даже Docker-Compose.
  • Запускатель discourse_docker делает множество предположений об окружении, в котором он работает. Например, он отказывается запускаться в rootless-режиме под Podman, выдавая ошибку об отсутствующих хранилищах, и при этом нельзя обойти это ограничение с помощью аргумента или переменной окружения.

В файле app.yml есть параметр version, который можно установить в нужную вам версию.

Используйте официальную установку, которая осуществляется через переход от отдельного контейнера к отдельным контейнерам для веб-части и данных.

Верно: мы стараемся сделать процесс удобным для вебмастеров, предлагая просто «перетащить содержимое этого zip-файла через FileZilla по FTP», одновременно обеспечивая, чтобы все использовали актуальные, поддерживаемые и обновлённые версии всего программного стека, включая базы данных.

Для более опытных администраторов Discourse подключение к внешней управляемой базе данных доступно через одну переменную окружения, согласно инструкции Настройка Discourse для использования отдельного сервера PostgreSQL.

Да, процесс, основанный на запуске launcher, из коробки не совместим с оркестрацией контейнеров. Однако его можно адаптировать, выполнив ./launcher bootstrap app, загрузив полученный образ в реестр контейнеров, а затем запустив этот образ через оркестратор.

Мы приветствуем pull request, который сделает это возможным, так как эта функция полезна в целом. pr-welcome

Мы пробовали это для создания развёртывания из версии 2.8, но это не сработало с ошибкой о неверной версии Discourse. Поскольку теперь мы можем воспроизвести это в нашем CI/CD, вы можете посмотреть на ошибку здесь: docker-build (#4121616927) · Jobs · idcohorts / RPS / Discourse Image Builder · GitLab

Вот что мы и делаем по сути. :slight_smile:

Спасибо, мы уже работаем над этим.

Это связано с тем, что Discourse 2.8 больше не поддерживается, поэтому мы не перенесли в него новейшую версию Ruby, и она работает на версии Ruby, которая уже устарела (EOL). Никто не должен использовать её в продакшене.

Готово, смотрите add bypasses for unsupported docker versions by mkbrechtel · Pull Request #706 · discourse/discourse_docker · GitHub

Тем не менее, технически это даже невозможно (просто изменив параметр версии), поэтому мы больше не можем воспроизводить старые окружения.

Ну, можно, нужно просто использовать более старое базовое изображение.

Как это сделать? Я искал, но решения не нашёл…

Вы буквально ссылаетесь на старый базовый образ (созданный примерно в дату выпуска, на которую вы ориентируетесь — очевидно, он должен быть как минимум более поздним)

Их целые страницы (и ещё страницы!):

Однако, если вы попытаетесь зафиксировать слишком старую версию, она может не работать с обновленными версиями базового образа Discourse. Я не помню конкретных примеров, но, например, старая версия Discourse не будет работать с Ruby 3.2, поэтому вам (иногда) также нужно фиксировать discourse_docker, если вы фиксируете старую версию Discourse.

Самое безопасное и в большинстве случаев наиболее эффективное решение — собрать образ и загрузить его в репозиторий, а не собирать новый образ при каждом развёртывании. И если у вас есть плагины, вам, скорее всего, придётся фиксировать и каждый из них.

Я делал это для нескольких клиентов как для ECS, так и для k8s на GCP и AWS.

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