Как собрать все статические ресурсы (js, css), используемые Discourse

Я пытаюсь настроить CDN для своего форума. Поскольку в Китае запретили Fastly и множество CDN-серверов, я не могу использовать их для ускорения работы форума. После некоторых исследований я обратился к jsDelivr, который может обслуживать статические файлы из npm или репозиториев GitHub.

Я знаю, что могу использовать переменную DISCOURSE_CDN_URL в файле app.yml для настройки URL. Но прежде чем это сделать, мне нужно собрать все статические файлы (js, CSS) с моего форума и загрузить их на GitHub, чтобы jsDelivr мог получить к ним доступ. Я обнаружил, что статические файлы на самом деле находятся внутри Docker-контейнера:

/var/www/discourse/app/assets

Поэтому я думаю о копировании всех файлов из этого пути каждый раз после пересборки приложения и их загрузке на GitHub. Кажется, эта идея должна сработать, но в реальном запросе используется длинное хэш-имя, и я не знаю, как его получить. Например:

ember_jquery.js превращается в
ember_jquery-8ef4e572f0bf9485e6ef9a35f088729735f82434cf495fbcd5acedefbcddb363.js

Таким образом, мой вопрос:

  1. Как сгенерировать имя файла с хэшем?
  2. Есть ли другой способ собрать статические ассеты?

Это SHA1-хеш содержимого файла. Он генерируется здесь:

Скомпилированные версии, которые используются, помещаются в /var/www/discourse/public/assets/.

Если вы добавите секцию в ваш app.yml, вы сможете выполнить действие после пересборки контейнера. Например, для загрузки в S3 мы используем что-то подобное:

hooks:
  after_assets_precompile:
    - exec:
        cd: $home
        cmd:
          - sudo -E -u discourse bundle exec rake s3:upload_assets

В вашем случае замените задачу rake на команды, которые вы выполняете для отправки скомпилированных ассетов в GitHub при сборке контейнера.

Спасибо, @schleifer. Ваш ответ очень полезен. Однако у меня есть ещё несколько уточняющих вопросов:

  1. Где можно найти документацию по хукам, таким как after_assets_precompile? Я искал в документации Docker, а также в репозитории Discourse на GitHub, но не нашёл никакой информации об этом. Мне нужно самостоятельно настроить хуки с именем after_assets_precompile (как это сделать?) или они уже настроены в Discourse, как, например, after_code?

  2. Насколько я понимаю, мой псевдокод будет выглядеть так:

     hooks:
       after_assets_precompile:
         - exec:
             cd: $home
             cmd:
               - войти в контейнер Docker
               - перейти в `/var/www/discourse/public/assets/`
               - выполнить git add, commit и push в репозиторий GitHub
    

Спасибо.

Вопрос хороший, но у меня нет на него хорошего ответа.

Система конфигурации, используемая внутри контейнера, описана здесь:

В файле README там объясняется, как работают хуки в целом. Конкретные доступные хуки зависят от того, как настроен ваш экземпляр — главный файл app.yml включает один или несколько шаблонов. В большинстве случаев одним из них является web.template.yml:

Именно там определяется хук assets_precompile (на строке [L159], на момент написания этого текста). Согласно документации по Pups, вы можете запускать другие команды до или после его выполнения с помощью before_assets_precompile и after_assets_precompile соответственно.

Команды выполняются внутри контейнера Docker, поэтому вам не нужно ничего делать для этого.

Директива cd: может указывать прямо на /var/www/discourse/public/assets/, и каждая строка в cmd выполняется из этого каталога. (Предупреждение: каждая строка в массиве cmd выполняется в отдельной оболочке, как в Makefile).

Я не уверен, будет ли содержимое /var/www/discourse/public/assets/ сохраняться между сборками, поэтому, возможно, вам придется создавать локальный репозиторий Git и выполнять принудительную отправку каждый раз. Более «правильным» решением может быть определение тома Docker для каталога активов в app.yml (как и для других) по аналогии с этим примером и обеспечение его сохранения вне контейнера.

Огромное спасибо. Я также обнаружил, что некоторые статические ресурсы (например, CSS) размещаются в /var/www/discourse/tmp/stylesheet-cache. Однако есть ещё две проблемы:

  1. Пользователи загружают ресурсы, такие как аватары, которые после настройки DISCOURSE_CDN_URL также обслуживаются через CDN. Но выгружать загруженные ресурсы в GitHub каждый раз после загрузки пользователем кажется не самым лучшим решением.
  2. Когда Discourse запрашивает аватар пользователя, например 2_2.png, он: 1) разбивает имя файла, 2) выполняет некоторые проверки, 3) вычисляет реальное имя файла с помощью хеширования. Если мне нужно обслуживать аватары пользователей, я должен реализовать эту же логику самостоятельно, поскольку файла с именем 2_2.png не существует.

Мое окончательное решение простое. 1) Я добавляю Nginx перед моим форумом, как в этом посте. 2) Собираю все статические ресурсы из указанного выше пути и выгружаю их в GitHub. 3) В конфигурационном файле Nginx добавляю правила, подобные следующим:

location ~/(stylesheets|assets) {
    return 301 https://cdn.jsdelivr.net/gh/my_github/my_repo/$request_uri;
}

Ещё раз спасибо, @schleifer