定义 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 中通过环境变量设置 s3_cdn_url(或手动编辑 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,它只会用于上传,而不会用于资源文件。

我认为你确实理解了,而且多亏了你,我也至少更接近于理解自己了!非常感谢!

遇到了这个问题,阅读了这个帖子后仍然非常困惑……

我尝试从 CDN(Cloudfront)提供 S3 上传的文件(非编译资源)。

如果通过设置界面配置“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 看来这应该作为一个 bug 提交,对吧?

也许吧。这个功能不太可能被普通自建用户用到,所以优先级会很低。另外,我认为全局设置和“被全局覆盖”的工作方式很快会有调整,到时候应该会一并解决。

看起来同样的问题在这里也把我拒之门外
@pfaffman 需要你的帮助
你是使用 CloudFront 来实现自定义域名的 CDN URL,还是直接在 CDN URL 中使用存储桶对象的公共前缀?

我刚刚遇到了这个问题。@pfaffman,你解决这个问题了吗?

我通过手动在站点设置中配置 s3_cdn_url 让上传功能正常工作,但理想情况下,我希望在部署时能全局设置该环境变量。当我这样做时,却遇到了同样的问题:Discourse 试图在 s3_cdn_url 中查找资源,我认为这看起来像是 discourse/lib/content_security_policy/default.rb at main · discourse/discourse · GitHub 中的一个 bug。

我想我刚刚已经在数据库中设置了该值。

我的猜测是,解决方案是找到将资源推送到 S3 的 rake 任务。

我想请问一下,@team 中的任何一位能否确认这是否是预期行为:即无法在不让 Discourse 也在此处查找资源的情况下,使用 S3 CDN(全局设置)来上传文件。除非我误解了什么,否则这似乎是一种出乎意料的行为。

是的,这就是预期行为。

配置 S3 CDN 后,它将用于所有静态文件,无论是上传的文件还是 JS 资源。

这里有一些相关信息,我上个月也处理过这个问题。

我的解决方法是同时设置两个变量(DISCOURSE_S3_CDN_URLDISCOURSE_CDN_URL),并创建两个 CloudFront 分发:一个用于上传文件,源站为 S3 存储桶;另一个用于资源文件,源站为服务器。

以下是我们使用的代码:

以下是我们的 app.yml(我们将其命名为 web.yml),我们在构建时替换变量:infra/modules/services/discourse/web.yml at master · debtcollective/infra · GitHub

太棒了,非常感谢。这方面似乎几乎没有文档,而且设置暗示你只能使用 S3 进行上传,我想这正是让我们所有人困惑的地方。

这已列入我的待办事项,我计划在本周末前写一篇关于此的#操作指南。

是的,一旦你明白需要两个 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_BUCKETDISCOURSE_S3_BUCKET 这两个环境变量。它们之间有什么区别?