DISCOURSE_S3_CDN_URL の定義: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 として設定しました。s3_cdn_url サイト設定に https://lc-XXX.literatehosting.com/uploads を入力すると、新しいアップロードは S3 バケットに保存され、画像は CDN URL にリンクされ、動作します。

しかしapp.yml 内の ENV で s3_cdn_url を設定しようとしたり(または手動で config/discourse.conf を編集して sv restart unicorn を実行したり)、すべてのアセットが S3(実際には存在しない場所)から読み込まれてしまいます。それは問題ないかもしれませんが、rake s3:upload_assets を実行すると、S3 が設定されていないとエラーが表示されます。

この件には、競合する設定名の解決中に偶然出くわしました。

私は(上記のスレッドで絶対的なナンセンスを書かなかった、つまりこれを理解できているという意味で)願っていますが、以下の 2 行を削除すれば:

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 助けが必要です。
カスタムドメインの CDN URL を実現するために CloudFront を使っていますか、それともバケットオブジェクトのパブリックプレフィックスを CDN URL で使っているだけですか?

これに遭遇しました。@pfaffman さんはこの問題を解決されましたか?

site settingss3_cdn_url を手動に設定することでアップロードは動作するようになりましたが、デプロイ時に ENV 変数をグローバルに設定したいと考えています。そうすると、同じ問題が発生します。Discourse が s3_cdn_url でアセットを検索しようとしており、これは discourse/lib/content_security_policy/default.rb at main · discourse/discourse · GitHub におけるバグのように思えます。

データベースに値を設定したと思います。

解決策は、アセットを S3 にプッシュする rake タスクを見つけることではないかと推測します。

@team の皆様にお伺いしたいのですが、アップロードに対して S3 CDN(グローバル設定)を使用する場合、Discourse 側もそのアセットを参照しようとするのは想定された動作でしょうか?何か見落としている可能性はありますが、これは予期しない動作のように思われます。

はい、それがその動作です。

S3 CDN を設定すると、アップロードファイルであれ JS アセットであれ、静的ファイルとして扱われるすべてのコンテンツにそれが使用されます。

これに関する情報を共有します。先月私も同様の問題に対処していました。

DISCOURSE_S3_CDN_URLDISCOURSE_CDN_URL の両方の変数を設定し、S3 バケットをオリジンとするアップロード用と、サーバーをオリジンとするアセット用の 2 つの CloudFront ディストリビューションを作成することで解決しました。

私たちが使用しているコードは以下の通りです。

また、当社の app.yml(web.yml という名前にしています)もこちらです。ビルド時に変数を置換しています: infra/modules/services/discourse/web.yml at master · debtcollective/infra · GitHub

素晴らしいです。どうもありがとうございます。これに関するドキュメントはほとんど見当たらず、設定からはアップロードにのみ S3 を使用できるという印象を受けます。それが皆を混乱させている原因だと思われます。

これについての howto を書くことは私のリストにあります。週末までには終わらせたいと思います。

はい、CloudFront ディストリビューションが 2 つ必要だと理解すれば、少しは分かりやすくなりますね。また、ビルドのたびにアセットを S3 にアップロードすることを忘れないでください。Docker Manager からのアップグレードには問題があり、Docker コンテナ内で bundle exec rake s3:upload_assets を手動で実行する必要があります。代わりにビルドを行う場合は、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_BUCKETDISCOURSE_S3_BUCKET という 2 つの環境変数を設定する必要があるように思えます。この 2 つの違いは何でしょうか?