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

我似乎没有维基编辑权限,但我确实成功使用了另一个提供商。

OVHcloud

服务名称:对象存储

区域对应于数据中心,数据中心由三字母代码标识。如果您不知道在哪里创建了存储桶,请在客户门户的对象存储选项卡中进行检查。

DISCOURSE_USE_S3: true
DISCOURSE_S3_REGION: [数据中心代码]
DISCOURSE_S3_ENDPOINT: https://s3.[数据中心代码].io.cloud.ovh.net/
DISCOURSE_S3_ACCESS_KEY_ID: [密钥]
DISCOURSE_S3_SECRET_ACCESS_KEY: [密钥]
DISCOURSE_S3_BUCKET: [存储桶名称]
DISCOURSE_S3_BACKUP_BUCKET: [存储桶名称]
DISCOURSE_BACKUP_LOCATION: s3
1 个赞

你是让 OVHcloud S3 用于上传还是仅用于备份?

最初我在测试版本中都这样做,但我在生产环境中只使用了备份,因为生产机器空间很充裕。

它与S3非常兼容,但缺少一些功能,比如删除旧文件或将它们移到冷存储的生命周期规则,OVH 正在积极开发这些功能。不过,用它来提供文件是没有问题的。

因此,对于备份,我只使用了Discourse自主删除旧备份的选项。

1 个赞

这是一个非常令人失望且完全无用的回复。到底是什么问题?链接到一个会更改的支持文档意味着没有人能确切地知道此处的“糟糕的损坏”指的是什么。
您提到了“元数据”以及 CDN“不知道它”。什么元数据?了解什么不起作用将会有所帮助。

我想在我的帖子中添加关于如何使用 iDrive E2 的说明。

iDrive 最近启用了一项功能,该功能会导致仅分配给一个存储桶的访问密钥失败,除非绕过存储桶身份验证检查。

您可以在 rclone.conf 文件中使用 no_check_bucket = true 来绕过 rclone 的此问题,但不确定 Discourse 构建是否存在这样的环境变量。

因此,使用 iDrive E2 时,您目前必须使用一个可以访问您所有存储桶的写入权限的密钥,而不是仅限于一个。

1 个赞

为什么别人会知道他们不使用的提供商的确切问题?

不过,看起来我们快要完成 Cloudflare R2 的设置了。根据:

当我将所有信息输入 Web UI 时,新上传已成功发送到 S3 存储,备份也已成功发送到 S3。显然,当前上传未移动。
然后我进入了 app.yml 并输入了这些信息:

## This set of lines allows R2 S3 hosted files to be uploaded and downloaded..
  DISCOURSE_CDN_URL: https://eufiles.technospider.com
  DISCOURSE_USE_S3: true
  DISCOURSE_S3_ENDPOINT: https://randomnumber.r2.cloudflarestorage.com
  DISCOURSE_S3_CDN_URL: https://eufiles.technospider.com
  DISCOURSE_S3_BACKUP_BUCKET: exotics-unlimited-backups
  DISCOURSE_INCLUDE_S3_UPLOADS_IN_BACKUPS: true
  DISCOURSE_BACKUP_LOCATION: s3
  DISCOURSE_S3_BUCKET: exotics-unlimited
  DISCOURSE_S3_REGION: auto
  DISCOURSE_S3_ACCESS_KEY_ID: randomnumbers
  DISCOURSE_S3_SECRET_ACCESS_KEY: randomnumbers
  DISCOURSE_S3_INSTALL_CORS_RULE: false

## The Docker container is stateless; all data is stored in /shared
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## Plugins go here
## see https://meta.discourse.org/t/19157 for details
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git
#         - git clone https://github.com/discourse/discourse-subscriptions.git
          - git clone https://github.com/discourse/discourse-follow.git
          - git clone https://github.com/discourse/discourse-solved.git
          - git clone https://github.com/communiteq/discourse-private-topics.git
#         - git clone https://github.com/discourse/discourse-assign.git
          - git clone https://github.com/tknospdr/discourse-auto-remove-group.git
          - git clone https://github.com/discourse/discourse-topic-voting.git
          - git clone https://github.com/discourse/discourse-livestream.git
#         - git clone https://github.com/discourse/discourse-calendar.git
          - git clone https://github.com/jannolii/discourse-topic-trade-buttons.git
##        - git clone https://github.com/tknospdr/force-tag-group-order.git

## Hooks for S3
  after_assets_precompile:
    - exec:
        cd: $home
        cmd:
          - sudo -E -u discourse bundle exec rake s3:upload_assets
          - sudo -E -u discourse bundle exec rake s3:expire_missing_assets

重建后,我的网站因大量文件丢失而损坏,因此我尝试将它们 rake 到服务器,并为每个文件收到此错误:

root@talk-app:/var/www/discourse# rake uploads:migrate_to_s3
Please note that migrating to S3 is currently not reversible! 
[CTRL+c] to cancel, [ENTER] to continue

Migrating uploads to S3 for 'default'...
Uploading files to S3...
 - Listing local files
 => 31 files
 - Listing S3 files
. => 4 files
 - Syncing files to S3
#<Thread:0x00007ff89dcbcb20 /var/www/discourse/lib/file_store/to_s3_migration.rb:212 run> terminated with exception (report_on_exception is true):
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.226.0/lib/seahorse/client/plugins/raise_response_errors.rb:17:in `call': You can only specify one non-default checksum at a time. (Aws::S3::Errors::InvalidRequest)
    from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-s3-1.182.0/lib/aws-sdk-s3/plugins/sse_cpk.rb:24:in `call'
    from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-s3-1.182.0/lib/aws-sdk-s3/plugins/dualstack.rb:21:in `call'
    from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-s3-1.182.0/lib/aws-sdk-s3/plugins/accelerate.rb:43:in `call'
    from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.226.0/lib/aws-sdk-core/plugins/checksum_algorithm.rb:169:in `call'
    from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.226.0/lib/aws-sdk-core/plugins/jsonvalue_converter.rb:16:in `call'
    from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.226.0/lib/aws-sdk-core/plugins/invocation_id.rb:16:in `call'
    from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.226.0/lib/aws-sdk-core/plugins/idempotency_token.rb:19:in `call'
    from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.226.0/lib/aws-sdk-core/plugins/param_converter.rb:26:in `call'
    from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.226.0/lib/seahorse/client/plugins/request_callback.rb:89:in `call'
    from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.226.0/lib/aws-sdk-core/plugins/response_paging.rb:12:in `call'
    from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.226.0/lib/seahorse/client/plugins/response_target.rb:24:in `call'
    from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.226.0/lib/aws-sdk-core/plugins/telemetry.rb:39:in `block in call'
    from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.226.0/lib/aws-sdk-core/telemetry/no_op.rb:29:in `in_span'
    from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.226.0/lib/aws-sdk-core/plugins/telemetry.rb:53:in `span_wrapper'
    from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.226.0/lib/aws-sdk-core/plugins/telemetry.rb:39:in `call'
    from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-core-3.226.0/lib/seahorse/client/request.rb:72:in `send_request'
    from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/aws-sdk-s3-1.182.0/lib/aws-sdk-s3/client.rb:17315:in `put_object'
    from /var/www/discourse/lib/file_store/to_s3_migration.rb:215:in `block (2 levels) in migrate_to_s3'

我很想得到一些建议,以便能够完成这项工作。

丢失的文件很可能是资源文件,因此您需要一个将这些文件推送到 s3 的 rake 任务(s3:upload_assets – 就在顶部附近)

但是您的错误很可能是由于新的 aws s3 库破坏了许多服务。因此,您需要设法降级 aws gem 或使用其他服务。

我认为可能有一个关于如何做到这一点的帖子。我在一两个网站上做过,但不确定如何以及在哪里记录了它。

我认为可能是这个话题

1 个赞

即使这是我放在 app.yml 文件中的更改,我也需要运行它吗?我以为它在那里是为了在重建期间自动推送文件?

刚试了一下。它的输出是:


root@talk-app:/var/www/discourse# rake s3:upload_assets
Installing CORS rules...
skipping
Skipping: assets/logo-single-3f9a3693.png
Skipping: assets/favicon-7e45025e.ico
Skipping: assets/logo-single-dev-0d38377d.png
Skipping: assets/push-notifications/posted-e02e1c60.png
Skipping: assets/push-notifications/watching_first_post-e02e1c60.png
Skipping: assets/push-notifications/README-d49cc975.md
(一大长串...)
Skipping: assets/plugins/footnote_extra-95ffab71.gz.js

你不应该这样做,但这些事情会让你的网站“损坏”(或者“损坏”对你来说意味着“图片丢失”吗?)使用 migrate_to_s3 上传图片只会影响图片。

我无法确切解释所有资源是如何已经上传的(网站上有什么损坏?如果你的S3设置已损坏,它们是如何上传的?)

你能上传你网站上的任何图片吗?

我现在无法在网站上进行任何操作。
请随意浏览一下,看看。https://eu.technospider.com

既然我的存储桶里似乎一切都已就绪,可能需要更新某个环境变量才能让一切正常工作。
如果我们能解决这个问题,我们就可以说 R2 已准备就绪。

此文件(以及其他许多文件)缺失 https://eufiles.technospider.com/extra-locales/ca382c69f8e6b85162b2ba58f2ce100bfe741966/en/mf.js?__ws=eu.technospider.com

这是您的 CDN 还是存储桶?您的存储桶中存在该文件吗?也许它在您的存储桶中,但您的 CDN 坏了?

这是我曾经配置 R2 的方法,我认为它奏效了。

            - "DISCOURSE_S3_REGION: 'auto'"
            - "DISCOURSE_S3_ENDPOINT: https://some-number.r2.cloudflarestorage.com"
            - "DISCOURSE_S3_ACCESS_KEY_ID: 'keyid'"
            - "DISCOURSE_S3_SECRET_ACCESS_KEY: 'secret'"
            - "DISCOURSE_S3_CDN_URL: 'https://r2.myforum.us/xyz'"
            - "DISCOURSE_CDN_URL: 'https://r2.literatecomputing.com'"
            - "DISCOURSE_S3_BUCKET: 'myforum/xyz'"
            - "DISCOURSE_S3_BACKUP_BUCKET: 'myforum/xyz/backups'"

所以这从未奏效?

1 个赞

“extra-locales”应该在哪里?我在容器内的“public”或“assets”下都看不到它。我应该去哪里找?

抱歉问了愚蠢的问题,但这对我是全新的尝试。
什么是我(的 CDN)或我的存储桶?

带有开头的连字符,以及所有单引号和双引号?我的 app.yml 文件里没有这些。我应该添加它们并重建来测试吗?
我的文件看起来就是这样,每个都缩进 2 个空格:

## 这组行允许上传和下载 R2 S3 托管的文件。
  DISCOURSE_CDN_URL: https://eufiles.technospider.com
  DISCOURSE_USE_S3: true
  DISCOURSE_S3_ENDPOINT: https://randomnumber.r2.cloudflarestorage.com
  DISCOURSE_S3_CDN_URL: https://eufiles.technospider.com
  DISCOURSE_S3_BACKUP_BUCKET: exotics-unlimited-backups
  DISCOURSE_INCLUDE_S3_UPLOADS_IN_BACKUPS: true
  DISCOURSE_BACKUP_LOCATION: s3
  DISCOURSE_S3_BUCKET: exotics-unlimited
  DISCOURSE_S3_REGION: auto
  DISCOURSE_S3_ACCESS_KEY_ID: randomnumbers
  DISCOURSE_S3_SECRET_ACCESS_KEY: randomnumbers
  DISCOURSE_S3_INSTALL_CORS_RULE: false

当我通过 Web UI 输入设置时,它奏效了,然后当我将所有内容放入 app.yml 文件时,我看到了你访问该网站时看到的结果。

当我访问您的一个资产时,我看到以下内容:

此对象不存在或在此 URL 上不可公开访问。请检查您正在查找的对象 URL,或联系所有者以启用公共访问。

如果您将主机名更改为您的 Cloudflare 端点,您可以查看 https://eufiles.technospider.com/extra-locales/ca382c69f8e6b85162b2ba58f2ce100bfe741966/en/mf.js?__ws=eu.technospider.com 是否有效。

您能在您的存储桶中找到该文件吗?您能访问它吗?

不知道,但这是我从浏览器开发者工具中复制的 URL。

所以,请先在您的存储桶中找到该文件,看看它是否存在,然后再弄清楚 CDN 为什么找不到它。

不。我使用不同的工具进行配置,但这些是我确信曾经对我有效的环境变量设置。

我明白了。这很令人沮丧。祝您好运。

我收到:

此 XML 文件似乎没有关联的样式信息。下面显示了文档树。
<Error>
<Code>InvalidArgument</Code>
<Message>Authorization</Message>
</Error>

我的端点是:
https://7100e60b936991e069a3230dc05d4976.r2.cloudflarestorage.com/exotics-unlimited/

我刚将

DISCOURSE_S3_CDN_URL: https://eufiles.technospider.com

更改为

DISCOURSE_S3_CDN_URL: https://eufiles.technospider.com/exotics-unlimited

现在我面临一个永远不会消失的加载指示器。
有进展吗?谁知道。 :slight_smile:

找到一个可以通过存储桶 URL 访问的资产,然后找到如何通过 CDN 访问同一个资产。

抱歉,我不知道。但什么是存储桶(bucket)与 CDN(内容分发网络)。

存储桶是您创建的“主目录”,所有文件都存放在其中。CDN 是遍布全球的大量服务器,它们会复制该存储桶的内容。您的存储桶通过创建连接时提供的网址进行识别,例如 cdn.example.com

R2 似乎会自动创建 CDN,如果您为存储桶提供自定义域名。这有点令人困惑,因为我实际上不必对 CDN 做任何事情。

我会看看我能弄清楚什么。

似乎无论我怎么尝试,都无法访问 R2 端点 URL 的任何对象。

https://7100***********dc05d4976.r2.cloudflarestorage.com/exotics-unlimited/assets/logo-815195ae.png

https://exotics-unlimited.7100***********dc05d4976.r2.cloudflarestorage.com/assets/logo-815195ae.png

给了我:

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Error>
<Code>InvalidArgument</Code>
<Message>Authorization</Message>
</Error>

但通过 CDN:

![discourse](upload://4axzzMIqD328iAou0u6qv18Avo8.png)

给了我:
discourse

因为错误提到了授权,我对此进行了一些研究,并发现了这个要点:

注意

默认情况下,只有某些文件类型会被缓存。要缓存存储桶中的所有文件,您必须设置一个“缓存所有内容”页面规则。

有关默认缓存行为以及如何自定义缓存行为的更多信息,请参阅默认缓存行为

从这个页面:Public buckets · Cloudflare R2 docs

我创建了一个“缓存所有内容”规则,但没有变化。