为上传配置与 S3 兼容的对象存储提供商

暂时搁置这个问题,因为它看起来本应能正常工作,但 R2 在内容编码方面似乎存在一些奇怪的问题,无论是上传时未设置标头还是其他原因。它会因类似 browser-detect-7af298cd000a967d2bdc01b04807eda2924a388584ea38ad84919b726283c2ed.gz.js 的 gz 资源而出现“无效或意外的令牌”错误。rake s3:upload_assets 命令似乎运行正常,但在浏览器端文件未能正确读取。

我不明白为什么使用 AWS S3 时,本地服务器 URL 的资源(这些资源在我们的现有 S3 上传存储桶中不存在)可以正常工作,而对于 R2,它却只希望使用 DISCOURSE_S3_CDN_URL 来加载资源。如果我能强制资源从服务器 URL 加载,这可能就能解决所有问题。

编辑:在 CF 上交流后,这似乎是问题所在,也是今天 R2 在未进行任何更改的情况下无法与 Discourse 一起使用的原因。我可以在 post hook 步骤中编写脚本删除 gz 资源,但我感觉今天我已经“偏离正轨”太远了:

R2 目前无法正确处理您 gzip 的文件。您必须上传未压缩的文件。Cloudflare 具有透明压缩功能,它会根据客户端可以处理的内容选择 identity、gzip 或 Brotli。这与 S3 不同。

2 个赞

干得好!这是 Cloudflare 关于为何无法正常工作的明确信息。非常感谢。我将很快将其复制到 OP 中。

2 个赞

再次感谢!我已更新 OP:

3 个赞

感谢您整理了这份指南!我使用 Minio 取得了一些成功。

对于其他尝试使用 Docker Compose 在本地设置它的人来说,您可以告诉 Docker 添加一个主机名别名,使其作为子域工作,如下所示:

  minio:
    image: minio/minio
    command: server --console-address :9001 /data
    ports:
      - "9000:9000"
      - "9001:9001"
    volumes:
      - ./data/minio:/data
    environment:
      MINIO_DOMAIN: minio.mydomain.com
    networks:
      default:
        aliases:
          - assets.minio.mydomain.com

在这种情况下,您需要设置 DISCOURSE_S3_ENDPOINT=http://minio.mydomain.com:9000DISCOURSE_S3_CDN_URL=//assets.minio.mydomain.com:9000,并将本地 /etc/hosts/ 文件设置为将子域指向 localhost。

这在大多数情况下都运行良好,但我确实注意到 Discourse 无法从没有端口 80443 的地址下载文件,因此上传图片可以工作,但在尝试下载它以调整大小时会失败。

我想也许可以在 Minio 部分或摘要中提到 DISCOURSE_S3_CDN_URL 必须是端口 80 或 443。

4 个赞

@Falco - 这是指他们的 Spaces CDN 如何处理 Content-Encoding: gzip 标头吗?这听起来与 Cloudflare R2 类似,即资产位置被设置为与上传 CDN 相同,所以 gzip 会中断?这是今天 R2 的情况

也许可以考虑为该行为添加一个开关,即从源站提供资源,而不是始终使用 DISCOURSE_S3_CDN_URL?如果这可以被视为潜在的配置更改,我很乐意去看看如何实现。

3 个赞

如果省略配置 DISCOURSE_S3_CDN_URL,应该就是这样,但由于这是一个奇怪的极端情况,并且可能导致昂贵的错误,因此它不是一种常见的配置。

3 个赞

是的,我明白。在这里添加一个新的全局设置布尔值 S3_ORIGIN_ASSETS(或者 S3_BROKEN_PROXY_FUDGE :slight_smile:),就像 测试脚本不压缩 那样,可以让 Digital Ocean Spaces 和 Cloudflare R2 存储和 CDN 开箱即用地与 Discourse 配合使用,这似乎是一个不错的增值功能,而且付出的努力不多?也许以后可以考虑。:heart_eyes_cat:

4 个赞

哦,我在 3.0.beta 的发布说明中看到添加了一些东西。我会试试看,除非我误解了它的用途?这可能会允许 Cloudflare R2 和 Digital Ocean Spaces 与它们的 CDN 一起使用,并进行一些奇怪的 gzip 操作。

1 个赞

不,那不相关。

3 个赞

该设置允许我指定本地站点作为源,以规避 js 资产需要位于 S3 站点上的需求(在本例中为启用了 CDN 的 Cloudflare 或 Digital Ocean Spaces)。感谢 @david 的更改,即使那不是他的初衷。

4 个赞

您是为资产 CDN 输入网站 URL 吗?真聪明!

1 个赞

大家好,有人知道这是否与 Discourse 有关吗?

这是我们尝试上传到之前“与 Discourse 一起使用”的 S3 存储中的文件的 XML:

<Error>
<Code>InvalidArgument</Code>
<Message>
Requests specifying Server Side Encryption with AWS KMS managed keys require AWS Signature Version 4.
</Message>
<ArgumentName>Authorization</ArgumentName>
<ArgumentValue>null</ArgumentValue>
<RequestId>ID</RequestId>
<HostId>
ID
</HostId>
</Error>
1 个赞

您在使用 AWS 吗?还是其他服务?

那个存储桶配置了服务器端加密吗?

有可能是某个库更新了,行为方式有所不同。

2 个赞

谢谢,我仔细检查了一下,自动配置似乎可行,但 S3 管理中的自定义密钥管理不起作用。

您知道 Discourse 是否支持此功能吗?

1 个赞

3 个帖子已拆分为新主题:为什么即使禁用了安全上传也要运行 UpdatePostUploadsSecureStatus?

这似乎最近已得到修复。
2023-3-16 更新日志 中,它列出了关于 gzip 文件处理的错误修复。

我们目前正在 discourse.aosus.org 上使用 R2 运行我们的 discourse 论坛(尚未运行 migrate_to_s3),并且似乎一切正常!到目前为止没有明显的问题。

  DISCOURSE_USE_S3: true
  DISCOURSE_S3_REGION: "us-east-1" # alias to auto
  #DISCOURSE_S3_INSTALL_CORS_RULE: true # it should be supported
  DISCOURSE_S3_ENDPOINT: S3_API_URL
  DISCOURSE_S3_ACCESS_KEY_ID: xxx
  DISCOURSE_S3_SECRET_ACCESS_KEY: xxxx
  DISCOURSE_S3_CDN_URL: your cdn url
  DISCOURSE_S3_BUCKET: BUCKET_NAME

是否有办法为备份指定单独的主机?如果可以将 R2 仅用于 CDN 相关内容,那就太好了。

2 个赞

没有。我认为这不太可能改变。

1 个赞

23 个帖子被拆分到一个新主题:配置对象存储时遇到问题

环境变量中的设置未在管理员界面中反映出来,这很奇怪。是覆盖了吗?管理员界面中的新 S3 设置会覆盖环境变量中的设置吗?

1 个赞

是的。环境变量会覆盖数据库中的值,并且不会在用户界面中显示。

4 个赞