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.)

I’m trying this again. I’ve got uploads going to s3. That works.

I configured cloudflare to CDN the site. If I enter https://lc-XXX.literatehosting.com/uploads in the s3_cdn_url site setting, new uploads go to the S3 bucket and the image is linked to the CDN url and it works.

BUT if I try to set the s3_cdn_url with an ENV in app.yml (or edit config/discourse.conf by hand and sv restart unicorn, all of the assets are loaded from S3 (where they aren’t). That might be OK, but if I try to rake s3:upload_assets, it complains that S3 isn’t configured.

I happened across this while figuring out some clashing settings names.

I think (and hope, because it means I understand this and didn’t write absolute nonsense in the thread linked above) that if you remove these two lines:

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

Then you can set DISCOURSE_S3_CDN_URL, and it will only be used for uploads, not assets.

저도 이해하고 있다고 생각합니다. 그리고 덕분에, 저도 이제 이해에 한 발짝 더 가까워진 것 같아요! 정말 감사합니다!

이 문제를 겪고 있는데, 이 스레드를 읽어도 여전히 매우 혼란스럽습니다…

저는 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 이 경우 버그로 보고하는 것이 맞지 않나요?

그럴 수도 있습니다. 일반 셀프 호스터들이 사용할 가능성이 낮은 기능이라 우선순위가 낮을 것입니다. 또한, 전역 설정과 전역에 의해 가려진(shadowed) 설정의 작동 방식이 곧 변경될 예정이므로, 그때 해결될 가능성이 높습니다.

여기서도 같은 문제가 발생하는 것 같습니다.
@pfaffman 도움 부탁드립니다.
커스텀 도메인 CDN URL을 위해 CloudFront를 사용하시나요, 아니면 CDN URL에서 버킷 객체의 공개 접두사를 그대로 사용하시나요?

방금 이 문제를 겪었습니다. @pfaffman 이 문제를 해결하신 적이 있으신가요?

사이트 설정에서 s3_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가 그 CDN에서 에셋도 함께 찾게 된다는 점입니다. 제가 무언가를 오해하고 있는 것이 아니라면, 이는 예상치 못한 동작으로 보입니다.

네, 그것이 의도된 동작입니다.

S3 CDN을 설정하면 업로드 파일이나 JS 에셋 등 모든 정적 파일에 대해 이를 사용하게 됩니다.

이 문제에 대한 정보를 공유합니다. 지난달에 이 문제를 직접 처리한 적이 있습니다.

두 변수(DISCOURSE_S3_CDN_URL와 DISCOURSE_CDN_URL)를 모두 설정하고, CloudFront 배포를 두 개 생성하여 문제를 해결했습니다. 하나는 S3 버킷을 오리지인으로 사용하는 업로드용, 다른 하나는 서버를 오리지인으로 사용하는 자산용입니다.

우리가 이 작업을 위해 사용하는 코드는 다음과 같습니다.

우리의 app.yml 파일(이름을 web.yml로 변경했습니다)은 빌드 시점에 변수를 치환하며, 링크는 다음과 같습니다: https://github.com/debtcollective/infra/blob/master/modules/services/discourse/web.yml

놀랍네요. 정말 감사합니다. 이 부분에 대한 문서가 거의 없는 것 같고, 설정을 보면 업로드에만 s3를 사용할 수 있는 것처럼 보이는데, 이게 우리를 모두 혼란스럽게 하는 것 같습니다.

이 주제에 대해 #howto를 작성할 계획을 세우고 있습니다. 이번 주말까지 완료할 수 있기를 바랍니다.

네, CloudFront 배포가 두 개 필요하다는 걸 이해하면 훨씬 더 말이 되죠. 또한, 각 재빌드 후에 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_BUCKET과 DISCOURSE_S3_BUCKET 환경 변수를 설정해야 하는 것 같습니다. 이 두 변수의 차이점은 무엇인가요?