Maxine
(Maxine)
1
我们在将 Discourse 论坛整体推送到生产环境之前,一直在进行构建、测试,并有意查找其中的漏洞。我刚刚将一个启用了 S3 上传功能的测试论坛从一台服务器迁移到了另一台服务器,但在恢复后,所有附件的 URL 都被重写成了论坛的 URL,而不是 S3 的 URL……
幸运的是,这只是一个测试论坛,所以我们并不太在意数据本身。不过,我希望能够:
A. 仍然修复这个问题。
B. 找到一种方法来减轻或防止这种情况在生产环境中发生。
受影响的不仅仅是帖子,还包括所有图片、媒体、内容和头像(这相当严重)……
有什么建议吗?
在恢复之前,您可以在目标站点的 app.yml 中配置 S3(而非通过管理面板)。一旦确认配置完成并能访问正确的存储桶,即可开始恢复操作,媒体文件将正确关联。
我们有一份关于以此方式配置 S3 的指南:Configure an S3 compatible object storage provider for uploads
Maxine
(Maxine)
3
你好,Kris
我们确实那样做了,结果就陷入了那种局面。
我将原始的 app.yml 原样复制到目标位置,然后对原始文件进行了备份。问题出在恢复环节:当我们执行恢复操作时,URL 被重写了,尽管实际上没有任何变更,而且 S3 上传功能依然处于启用状态。
我们最终通过重新构建(rebuild)解决了这个问题(我们认为如此,但 Discourse 的缓存机制非常激进,在我们尝试的众多解决方案中,我们其实并不确定具体是哪一步起了作用)。不过,关于如何以最小问题执行迁移,或者在必要时从备份恢复到生产环境,这些疑问仍未得到解答。
gerhard
(Gerhard Schlager)
4
这听起来像是你通过站点设置配置了 S3,而不是像 Kris 建议的那样使用环境变量。恢复过程需要知道 S3 的相关信息,而通过站点设置无法实现这一点。
如果你愿意,也可以在控制台中创建不包含上传文件的备份:discourse backup --sql_only
恢复此类备份不会重写上传 URL。因此,只要你的新服务器能够访问相同的 S3 存储桶,这种方法就能奏效。
Maxine
(Maxine)
5
S3 配置位于 app.yml 中,而非站点设置。
编辑:
我意识到自己解释得不够详尽,也无意隐瞒细节。
我们使用的是 OVH S3,其配置在 app.yml 中。
我曾备份过不含上传内容的测试论坛,但当时 S3 仍处于启用状态。
随后,我使用完全相同的 app.yml 将其恢复到新站点,问题便由此产生。需要说明的是,目前问题已解决,但我不确定是因为我多次重新构建镜像,还是 Discourse 的缓存机制过于激进。正因如此,我需要了解正确的操作流程,确保首次操作即可成功。我担心的是,如果将来需要将备份恢复到生产环境并再次遇到此问题,我必须清楚如何立即修复,以免用户察觉。
gerhard
(Gerhard Schlager)
7
正如我所说的,如果您想在同一个 S3 存储桶的服务器上恢复,请确保在 app.yml 中配置了 S3,并创建一个不含上传文件的备份(discourse backup --sql_only)。当备份不包含上传文件时,上传 URL 不会被重写。
如果您想在不同的 S3 存储桶或完全未配置 S3 的服务器上恢复,请使用包含上传文件的完整备份。在恢复过程中,上传 URL 会被重写。
您是否 100% 确定已在两台服务器的 app.yml 中通过环境变量配置了 OVH S3,并使用了不含上传文件的备份(.sql.gz 文件扩展名)?
Maxine
(Maxine)
8
是的,我确实做了。
当我最初在上传完成后进行恢复时,系统实际上出错了,所以我不得不彻底清除并重新开始,这次是在没有上传的情况下进行备份。问题就是从那里开始的。URL 仍然被错误地写入。
app.yml 没有进行任何更改。
gerhard
(Gerhard Schlager)
9
我不确定这是怎么发生的。当你恢复 .sql.gz 文件时,恢复过程会跳过所有与上传相关的代码(包括上传 URL 的重写)。
也许我们说的不是同一件事?我指的是 uploads 表中的 url 列,通常是 //your-s3-bucket/original/...,而在本地环境中则是 /uploads/original。
恢复 .sql.gz 文件的一个注意事项是,不会重写任何 URL。它期望服务器可以通过与创建备份时相同的域名访问。如果你更改了域名,则需要重新映射 URL。
Maxine
(Maxine)
10
因此,回答所有这些问题:
- 没有更改任何主机名。仅更新了 A 记录,已完成备份。
- 用户头像缺失(这是因为我没有迁移 uploads 文件夹)。附件/媒体的 S3 图片已针对论坛 URL 重新编写,而非存储桶 URL。
因此,虽然我原本期望上述 S3 上传的 URL 会写成 https://some-bucket-name-here.s3.bhs.io.cloud.ovh.net/optimized,但实际上却是 https://forum.somedomainhere.com/uploads/optimized,这显然无法正常工作。
如果您希望我验证我所采取的所有步骤,我可以再次直接启动另一台虚拟机并进行完整恢复。
gerhard
(Gerhard Schlager)
11
好的,请这样做。同时查看恢复过程的输出。当你恢复 .sql.gz 文件时,输出中不应提及任何 URL 重映射。
Maxine
(Maxine)
12
我通过从存储在 S3 中的 sql.gz 文件进行恢复,到目前为止,唯一受影响的是部分用户头像和一些帖子,但我猜这是因为它们在创建时并未上传到 S3。
在生产环境中,假设从启动开始一切顺利且所有内容都存储在 S3 中……如果我从备份进行恢复,就不会出现与初始帖子中描述的相同奇怪问题,对吧?