# 配置兼容S3的对象存储提供商用于上传

**URL:** <https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916>\
**Category:** Self-Hosting\
**Tags:** cdn, configuring, how-to, reference\
**Created:** [2020年四月22日 22:37 UTC](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916 "2020-04-22T22:37:37Z")\
**Posts on this page:** 20\
**Page:** 10

<div class="post-metadata">

**Author:** ![markersocial](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/markersocial/32/170136_2.png) [@markersocial](https://meta.discourse.org/u/markersocial)\
**Post date:** [2023年四月29日 08:13 UTC](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916/415 "2023-04-29T08:13:53Z")

</div>

@Falco - 最好为 Scaleway 添加一个警告，说明它仅支持 1,000 个分片进行分片上传，而 AWS 支持 10,000 个。这对于常规上传不是问题，但对于超过一定大小的备份上传来说却是个问题，因为 S3 SDK 将使用 10,000 个分片，除非手动修改，否则会失败。

> **[Managing multipart uploads | Scaleway Documentation](https://www.scaleway.com/en/docs/object-storage/api-cli/multipart-uploads/)**
>
> Manage large object uploads efficiently with multipart uploads in Scaleway.

---

<div class="post-metadata">

**Author:** ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)\
**Post date:** [2023年四月29日 15:41 UTC](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916/416 "2023-04-29T15:41:44Z")

</div>

太棒了！如果可以的话，请将其添加到 OP wiki 中。

---

<div class="post-metadata">

**Author:** ![charlot\_Johanson](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/charlot_johanson/32/306823_2.png) [@charlot\_Johanson](https://meta.discourse.org/u/charlot_Johanson)\
**Post date:** [2023年五月13日 09:46 UTC](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916/417 "2023-05-13T09:46:49Z")

</div>

谢谢，另外我想补充的是，您可以使用以下任何工具将数据从云复制到云，特别是复制到/从 S3 兼容对象存储，例如 Rclone、Shargate、Gs Richcopy360 和 GoodSync。所有这些都与类似的云兼容。

---

<div class="post-metadata">

**Author:** ![aosus](https://avatars.discourse-cdn.com/v4/letter/a/ed8c4c/32.png) [@aosus](https://meta.discourse.org/u/aosus)\
**Post date:** [2023年六月8日 18:02 UTC](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916/418 "2023-06-08T18:02:57Z")

</div>

我们刚刚发现了一个问题，Cloudflare R2 不允许从 S3 端点 URL 进行公共读取，而只允许自定义域名或随机的 `r2.dev` 域名。  
（预签名下载可以工作，只是不支持直接公共访问。）  
但是 Discourse 只为嵌入式图像使用 CDN URL，而不为使用 S3 端点 URL 的直接下载使用。  
有没有办法让它为所有文件使用 CDN URL，或者强制使用预签名 URL？

相关：

> [@S3 CDN URL not being used on non-image uploads](https://meta.discourse.org/t/s3-cdn-url-not-being-used-on-non-image-uploads/175332/9):
>
> Ok so I found the place where [Markdown for attachments is generated](https://github.com/discourse/discourse/blob/v2.8.0.beta11/app/assets/javascripts/discourse/app/lib/uploads.js#L269) and as far as I understand the plugin API one cannot (easily) override it (I even think one should not do it). So my initial thought of adding a ?dl=1 param to those urls seems like the wrong way to do it. Regarding not-forcing downloads for resolved short-urls: If I understand [the argument against public ACLs on S3 buckets](https://meta.discourse.org/t/s3-cdn-url-ignored-when-uploading-into-posts/54898/4) correctly, one should either: serve files from S3 via a CDN (unfeasible for attachments as @martin poi…

该帖子中提到的解决方法有效，添加 `?dl=1` 可以解决此问题，因为它强制 Discourse 使用预签名的 S3 URL。

---

<div class="post-metadata">

**Author:** ![ARHAEEM](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/arhaeem/32/310459_2.png) [@ARHAEEM](https://meta.discourse.org/u/ARHAEEM)\
**Post date:** [2023年六月15日 23:57 UTC](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916/419 "2023-06-15T23:57:22Z")

</div>

> [@Falco](#):
>
> ### Cloudflare
> 
> Cloudflare 的产品不兼容。在测试中，@fearlessfrog 向 Cloudflare 提交了一个工单，在 2022 年 12 月他们表示：
> 
> > [@](#):
> >
> > 您压缩的（gzip）文件目前 R2 无法正确处理。您必须上传未压缩的文件。Cloudflare 具有透明压缩功能，他们会根据客户端可以处理的内容选择 identity、gzip 或 Brotli。这与 S3 不同。

已在 [2023-03-16](https://developers.cloudflare.com/r2/reference/changelog/#2023-03-16) 中修复，现在 R2 配合 Discourse 免费套餐运行得非常顺畅。

---

<div class="post-metadata">

**Author:** ![markschmucker](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/markschmucker/32/141599_2.png) [@markschmucker](https://meta.discourse.org/u/markschmucker)\
**Post date:** [2023年六月27日 05:55 UTC](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916/420 "2023-06-27T05:55:09Z")

</div>

> [@pfaffman](#):
>
> 但备份经常会静默失败，备份文件仍留在本地机器上，占满了磁盘。我查看了 wasabi 和 Discourse 的错误日志，但从未找到任何能让任何一方“修复”问题的解释。

我也经常（每隔几个月）遇到这种情况，尽管我的 Discourse 运行在 AWS Lightsail 上，并且我正在上传到 AWS S3。所以我不确定这是否是 wasabi 的问题。

是否有可能捕获此错误并通知管理员？我确实会检查磁盘空间并在升级时删除旧备份，但有时为时已晚，论坛会因为磁盘空间不足而宕机。

---

<div class="post-metadata">

**Author:** ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)\
**Post date:** [2023年六月27日 14:43 UTC](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916/421 "2023-06-27T14:43:45Z")

</div>

> [@markschmucker](#):
>
> 我也经常（每隔几个月）遇到这种情况，尽管我的 Discourse 运行在 AWS Lightsail 上，并且我正在上传到 AWS S3。所以我不确定这是 wasabi 的错。

我相当确定问题在于安全更新的自动操作系统重启发生在备份运行时。请确保您安排操作系统重启和备份在不同的时间进行。我是在将该网站从 wasabi 迁移出来之后才想出这个解释的，但我很确定就是这个原因。

---

<div class="post-metadata">

**Author:** ![markschmucker](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/markschmucker/32/141599_2.png) [@markschmucker](https://meta.discourse.org/u/markschmucker)\
**Post date:** [2023年六月29日 07:31 UTC](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916/422 "2023-06-29T07:31:35Z")

</div>

`uptime` 显示已运行 300 天，所以我认为那不是问题。但类似地，我在凌晨 2 点安排了 Discourse 备份，在凌晨 2:30 安排了 Lightsail 快照，所以也许上传有时未完成，快照会干扰它。我已将这两个操作分开一小时——我们拭目以待它是否会产生影响。

无论如何，我认为如果上传因任何原因失败，都应该向管理员发出警告是合理的。

---

<div class="post-metadata">

**Author:** ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)\
**Post date:** [2023年六月29日 14:27 UTC](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916/423 "2023-06-29T14:27:35Z")

</div>

是时候进行内核升级并重启了。 🙂

您是不是内存快用完了？

---

<div class="post-metadata">

**Author:** ![Brandon007](https://avatars.discourse-cdn.com/v4/letter/b/b4bc9f/32.png) [@Brandon007](https://meta.discourse.org/u/Brandon007)\
**Post date:** [2023年七月25日 03:45 UTC](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916/424 "2023-07-25T03:45:40Z")

</div>

实施远程 Backblaze 备份后，我在仪表板中看到此错误：

> **服务器配置为将文件上传到 S3，但未配置 S3 CDN。这可能导致高昂的 S3 成本和较慢的网站性能。请参阅“使用对象存储进行上传”了解更多信息。**

我没有配置文件的上传，我只通过以下配置配置了备份：

```plaintext
DISCOURSE_S3_REGION: "s3.us-west-00X"
DISCOURSE_S3_INSTALL_CORS_RULE: false
DISCOURSE_S3_ENDPOINT: https://s3.us-west-00X.backblazeb2.com
DISCOURSE_S3_ACCESS_KEY_ID: mykeyid
DISCOURSE_S3_SECRET_ACCESS_KEY: myaccesskey
DISCOURSE_S3_BUCKET: community-forum
DISCOURSE_S3_BACKUP_BUCKET: community-forum/backups
DISCOURSE_BACKUP_LOCATION: s3

```

我是否做错了什么？

似乎有些配置错误，我注意到当我尝试将文件上传到帖子时，我收到了此错误：

> 罐装 ACL ‘public-read’ 的值不受支持

如果您能提供任何帮助，我将不胜感激。

---

<div class="post-metadata">

**Author:** ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)\
**Post date:** [2023年七月25日 10:45 UTC](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916/425 "2023-07-25T10:45:17Z")

</div>

> [@Brandon007](#):
>
> `DISCOURSE_S3_BUCKET: community-forum`

如果您不希望上传到 s3，请删除此项。

---

<div class="post-metadata">

**Author:** ![Brandon007](https://avatars.discourse-cdn.com/v4/letter/b/b4bc9f/32.png) [@Brandon007](https://meta.discourse.org/u/Brandon007)\
**Post date:** [2023年七月25日 12:52 UTC](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916/426 "2023-07-25T12:52:17Z")

</div>

哥们，你帮了大忙。👍🏼 非常感谢！

---

<div class="post-metadata">

**Author:** ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)\
**Post date:** [2023年七月25日 13:21 UTC](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916/427 "2023-07-25T13:21:58Z")

</div>

> [@markschmucker](#):
>
> 我将两次操作间隔了一小时——看看是否会有所不同。

这样做有效吗？

---

<div class="post-metadata">

**Author:** ![markschmucker](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/markschmucker/32/141599_2.png) [@markschmucker](https://meta.discourse.org/u/markschmucker)\
**Post date:** [2023年七月26日 01:28 UTC](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916/428 "2023-07-26T01:28:22Z")

</div>

自从我将两个进程分开一小时以来，上个月发生了一次，所以它没有“修复”它，而且它发生的频率不够高，无法判断它是否有帮助。

从好的方面来看，我注意到管理页面上有一个备份状态部分，显示可用磁盘空间，这使我不必一直打开终端并执行 df 来检查卡住的备份。我自定义了文本，提醒自己预计有 80 GB 的可用空间。

 ![image](https://global.discourse-cdn.com/meta/original/4X/3/e/d/3ed5aba32276ced60c01598632931da811c0e46b.png)

---

<div class="post-metadata">

**Author:** ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)\
**Post date:** [2023年七月26日 11:16 UTC](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916/429 "2023-07-26T11:16:45Z")

</div>

> [@markschmucker](#):
>
> 我自定义了文本，提醒自己预计有 80 GB 的可用空间

这是个好主意。

在我读到你自定义了文本之前，我看到了这张图片，当时就在想，是什么逻辑判断出这是“好的”！

---

<div class="post-metadata">

**Author:** ![noplanman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/noplanman/32/217783_2.png) [@noplanman](https://meta.discourse.org/u/noplanman)\
**Post date:** [2023年八月6日 14:55 UTC](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916/430 "2023-08-06T14:55:22Z")

</div>

我无法使用 Scaleway 和 [Bitnami Discourse](https://hub.docker.com/r/bitnami/discourse) 镜像来完成此操作。  
环境变量已设置，但显然没有被正确读取/应用（或者根本没有？）。

因此，我在管理员面板中设置了 S3 变量，并在 rails 控制台中直接设置了区域（仍然希望这只是一个文本字段）：  
`SiteSetting.s3_region="fr-par"`

这给了我一个验证错误，但在更新设置之前，我只是注释掉了验证检查，然后又将其放了回去。

---

<div class="post-metadata">

**Author:** ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)\
**Post date:** [2023年八月6日 17:30 UTC](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916/431 "2023-08-06T17:30:27Z")

</div>

> [@noplanman](#):
>
> 我无法使用 [Bitnami Discourse](https://hub.docker.com/r/bitnami/discourse) 镜像在 Scaleway 上成功运行。

Bitnami 镜像不是由我们打包的，也不遵循我们的建议。此处记录的所有内容仅针对官方安装进行了测试。

---

<div class="post-metadata">

**Author:** ![aosus](https://avatars.discourse-cdn.com/v4/letter/a/ed8c4c/32.png) [@aosus](https://meta.discourse.org/u/aosus)\
**Post date:** [2023年九月17日 09:06 UTC](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916/432 "2023-09-17T09:06:00Z")

</div>

这已通过启用“s3 use cdn url for all uploads”得到解决，这是 discourse 最近添加的一个选项。  
由于我们之前使用的是 R2，因此我们需要使用 `discourse remap` 手动替换损坏的链接，并同步 s3 文件以防万一，然后我们重新烘焙了所有帖子。

---

<div class="post-metadata">

**Author:** ![thepaperpilot](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/thepaperpilot/32/245602_2.png) [@thepaperpilot](https://meta.discourse.org/u/thepaperpilot)\
**Post date:** [2023年十月14日 15:35 UTC](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916/434 "2023-10-14T15:35:11Z")

</div>

我正在尝试使用 idrive e2 进行设置，它是 s3 兼容的。但是，在 `./launcher rebuild app` 的末尾，我收到了一条非常有帮助的错误/堆栈跟踪：

```plaintext
I, [2023-10-14T15:08:08.026184 #1] INFO -- : cd /var/www/discourse & sudo -E -u discourse bundle exec rake s3:upload_assets
rake aborted!
Aws::S3::Errors::InternalError: 我们遇到了内部错误，请重试。
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-core-3.130.2/lib/seahorse/client/plugins/raise_response_errors.rb:17:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/sse_cpk.rb:24:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/dualstack.rb:27:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/accelerate.rb:56:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/checksum_algorithm.rb:111:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/jsonvalue_converter.rb:22:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/idempotency_token.rb:19:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/param_converter.rb:26:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-core-3.130.2/lib/seahorse/client/plugins/request_callback.rb:71:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/response_paging.rb:12:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-core-3.130.2/lib/seahorse/client/plugins/response_target.rb:24:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-core-3.130.2/lib/seahorse/client/request.rb:72:in `send_request'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/client.rb:12369:in `put_object'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/object.rb:1472:in `put'
/var/www/discourse/lib/s3_helper.rb:78:in `upload'
/var/www/discourse/lib/tasks/s3.rake:41:in `block in upload'
/var/www/discourse/lib/tasks/s3.rake:41:in `open'
/var/www/discourse/lib/tasks/s3.rake:41:in `upload'
/var/www/discourse/lib/tasks/s3.rake:197:in `block (2 levels) in <main>'
/var/www/discourse/lib/tasks/s3.rake:197:in `each'
/var/www/discourse/lib/tasks/s3.rake:197:in `block in <main>'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/exe/rake:27:in `<top (required)>'
/usr/local/bin/bundle:25:in `load'
/usr/local/bin/bundle:25:in `<main>'
Tasks: TOP => s3:upload_assets
(See full trace by running task with --trace)
I, [2023-10-14T15:08:16.413098 #1] INFO -- : Installing CORS rules...
skipping
Uploading: assets/admin-2ebebf57104b0beb47a1c82fe5a8c6decd07f60a706640345fed296a094d1536.js

```

这是我一直在使用的配置，但我也尝试过使用 `DISCOURSE_S3_CONFIGURE_TOMBSTONE_POLICY` 和 `DISCOURSE_S3_HTTP_CONTINUE_TIMEOUT`

```plaintext
  DISCOURSE_USE_S3: true
  DISCOURSE_S3_REGION: Dallas
  DISCOURSE_S3_ENDPOINT: https://y0o9.tx21.idrivee2-4.com
  DISCOURSE_S3_ACCESS_KEY_ID: <snip>
  DISCOURSE_S3_SECRET_ACCESS_KEY: <snip>
  DISCOURSE_S3_BUCKET: discourse
  DISCOURSE_S3_INSTALL_CORS_RULE: false

```

请注意，我没有将其用于备份（这已经在 UI 中使用 backblaze 设置好了），也没有使用 DISCOURSE\_CDN\_URL，因为我不确定 idrive 是否支持该功能——我计划在将实际文件放入存储桶后进行实验。

---

<div class="post-metadata">

**Author:** ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)\
**Post date:** [2023年十月14日 15:36 UTC](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916/435 "2023-10-14T15:36:55Z")

</div>

它似乎与 S3 的兼容性不足，无法满足 Discourse 的需求。

如果您想进一步研究，下一步是在开发环境中重现此问题，并找出失败的确切 API 调用。

[上一頁](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916.md?page=9)

[下一頁](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916.md?page=11)
