Defining DISCOURSE_S3_CDN_URL links to assets in S3 CDN URL

I had this problem before and decided that I was crazy, confused, or the database on the site was suspect, but this is on a brand new site. Also, I was on Digital Ocean spaces, so I thought it might be a problem somehow.

I’m trying again to figure out how to keep images on AWS S3 like I think the Big Boys do.

Here’s what I have in the env section:

  DISCOURSE_S3_ACCESS_KEY_ID: 'key'
  DISCOURSE_S3_SECRET_ACCESS_KEY: 'lock'
  DISCOURSE_BACKUP_LOCATION: 's3'
  DISCOURSE_S3_BUCKET: 'lc-xyz'
  DISCOURSE_S3_BUCKET_NAME: 'lc-xyz'
  DISCOURSE_S3_BACKUP_BUCKET: 'lc-xyz/backups'
  DISCOURSE_S3_UPLOAD_BUCKET: 'lc-xyz/uploads'
  DISCOURSE_S3_CDN_URL: 'https://lc-rbx.s3.amazonaws.com'

When I include the s3 cdn url the site breaks because all of the links to the assets are on S3 like https://lc-xyz.s3.amazonaws.com/assets/plugin-third-party-01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b.br.js.

Because if you define s3 cdn url Discourse looks for the assets on the s3_cdn_url.

I did a rebuild, but the assets are still missing. I can do a

rake s3:upload_assets

Is there an after_bundling_assets stanza that I could add that to? (I know about after_db_migrate and after_bundle_exec, but don’t know if those would work.)

Do assets get produced some other time? (It would seem like when themes get modified assets would change.)

If I also had a “push CDN like normal”, would that keep this from happening?

Is there some best practice that I’m missing?

You can use after_assets_precompile as the hook for that rake task.

Aha! Thanks very much for that. Where does the list of those things live?

I’m still confused why this is necessary, especially since you seemed confused before. (Or maybe I should be happy that I can push all this stuff to S3, now that I know how to do it–And I think that it was you who said that one could use CloudFlare’s free CDN to front an AWS bucket.)

Я пытаюсь сделать это снова. Загрузка в S3 работает.

Я настроил Cloudflare как CDN для сайта. Если я ввожу https://lc-XXX.literatehosting.com/uploads в настройке сайта s3_cdn_url, новые файлы загружаются в бакет S3, изображение ссылается на URL CDN, и всё работает.

НО если я пытаюсь установить s3_cdn_url через ENV в app.yml (или вручную отредактировать config/discourse.conf и выполнить sv restart unicorn), все ресурсы загружаются из S3 (где их нет). Возможно, это приемлемо, но если я попробую выполнить rake s3:upload_assets, система сообщит, что S3 не настроен.

Я наткнулся на это, когда разбирался с конфликтующими именами настроек.

Мне кажется (и я очень на это надеюсь, потому что это значит, что я всё понял и не написал полной ерунды в связанной выше ветке), что если удалить эти две строки:

DISCOURSE_S3_BUCKET: 'lc-xyz'
DISCOURSE_S3_BUCKET_NAME: 'lc-xyz'

то можно задать DISCOURSE_S3_CDN_URL, и он будет использоваться только для загрузок, а не для ассетов.

Думаю, что вы действительно понимаете, и благодаря вам я хотя бы стал ближе к пониманию сам! Большое спасибо!

Сталкнулся с этой проблемой и до сих пор в замешательстве, прочитав эту тему…

Я пытаюсь отдавать загрузки S3 (не скомпилированные ресурсы) через CDN (Cloudfront).

Если я настраиваю «s3 cdn url» через экран настроек, всё работает как ожидалось (хотя… кроме System upload not using s3 cdn url).

Однако, если я настраиваю это через DISCOURSE_S3_CDN_URL и пересобираю приложение, фронтенд ломается, потому что он пытается загрузить скомпилированные ресурсы с моего S3 CDN URL.

Кажется, DISCOURSE_S3_CDN_URL / s3_cdn_url должны влиять только на загрузки, а DISCOURSE_CDN_URL — только на ресурсы.

У меня тоже такой опыт. В итоге я создал плагин для установки S3_CDN_URL.

@pfaffman Похоже, это стоит оформить как ошибку, верно?

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

Кажется, та же проблема здесь отклоняет меня
@pfaffman нужна ваша помощь
вы используете Cloudfront для получения URL CDN с пользовательским доменом или просто используете публичный префикс объектов бакета в URL CDN

Я только что столкнулся с этим. @pfaffman, удалось ли вам решить эту проблему?

Мне удалось настроить загрузку файлов, вручную указав s3_cdn_url в настройках сайта, но в идеале мне нужно иметь возможность устанавливать переменную окружения глобально при развёртывании. Когда я это делаю, возникает та же проблема: Discourse пытается искать ресурсы по адресу s3_cdn_url, что, по моему мнению, является ошибкой в discourse/lib/content_security_policy/default.rb at main · discourse/discourse · GitHub

Думаю, я просто установил значение в базе данных.

Мое предположение: решение заключается в поиске задачи Rake, которая выгрузит ассеты в S3.

Мне интересно, может ли кто-то из @team подтвердить, что это ожидаемое поведение: нельзя использовать S3 CDN (настроенный глобально) для загрузки файлов, если Discourse также не ищет там ресурсы. Это кажется неожиданным поведением, если только я что-то не неправильно понимаю.

Да, это именно так.

Настройка CDN для S3 обеспечит его использование для всех статических файлов, будь то загруженные файлы или JS-ресурсы.

Вот информация по этому вопросу, я сталкивался с этим в прошлом месяце.

Я исправил это, установив обе переменные (DISCOURSE_S3_CDN_URL и DISCOURSE_CDN_URL) и создав два дистрибутива CloudFront: один для загрузок с источником в виде S3-бакета, и другой для ассетов с источником на сервере.

Вот код, который мы используем для этого:

Вот наш файл app.yml (мы назвали его web.yml), переменные в котором заменяются во время сборки: infra/modules/services/discourse/web.yml at master · debtcollective/infra · GitHub

Удивительно. Большое спасибо. Похоже, что документации по этому вопросу практически нет, а настройки подразумевают, что S3 можно использовать только для загрузки файлов, что, по-видимому, и вводит всех в заблуждение.

Это есть в моем списке — написать howto по этой теме. Надеюсь, сделаю это к выходным.

Да, как только поймёте, что нужны две дистрибуции CloudFront, всё становится понятнее. Также не забудьте загружать ассеты в S3 после каждой пересборки. Есть проблема с обновлениями из Docker Manager: требуется вручную выполнить bundle exec rake s3:upload_assets внутри контейнера Docker. Если вместо этого сделать пересборку, всё должно работать, если добавить эти строки в ваш app.yml:

hooks:
  after_assets_precompile:
    - exec:
        cd: $home
        cmd:
          - 'bundle exec rake s3:upload_assets'

Эта задача жалуется на то, что у меня не настроен S3. Я сузил проблему до этого метода в global_setting.rb:

def self.use_s3?
    (@use_s3 ||=
      begin
        s3_bucket &&
        s3_region && (
          s3_use_iam_profile || (s3_access_key_id && s3_secret_access_key)
        ) ? :true : :false
      end) == :true
  end

Где должно быть определено GlobalSetting.s3_bucket? Похоже, нам нужно установить переменные окружения DISCOURSE_S3_UPLOAD_BUCKET и DISCOURSE_S3_BUCKET. В чём разница между ними?