需要在路径下设置多个复杂的 Apache ProxyPass 规则,以及用户头像图片上传问题

你好。

我们有一个 v2.4.0.beta2 +346 版本的 Discourse 安装,最初部署在 include.metaring.com 上。

该安装使用 Ubuntu 上的 Apache HTTP Server,其配置如下:

  • 将所有 HTTP 请求重定向到 HTTPS
  • 自行管理 SSL 证书(LetsEncrypt)
  • 所有请求通过代理重定向至 nginx http sock,因此 Discourse Docker 的 80 和 443 端口已禁用/未使用

我们执行了以下操作:
./launcher enter app
rails c
[1] pry(main)> SiteSetting.force_https = true
=> true

以确保所有内容都通过 HTTPS 提供(如果不这样做,会出现多个错误)。

一切运行正常。

随后,我们决定将应用程序(不修改数据库或其他内容)迁移到 include.metaring.com/discourse 路径下,并相应地编辑了 app.yml 文件:

  • DISCOURSE_HOSTNAME: include.metaring.com <— 保持不变,与之前相同
  • DISCOURSE_RELATIVE_URL_ROOT: /discourse

为了极其确保配置正确,我们执行了:
./launcher stop app
./launcher destroy app
./launcher cleanup
./launcher rebuild app

当然,我们也在 Apache 配置文件中添加了规则,以正确地将 /discourse 路径代理到 *unix:/../../nginx.http.sock|http://localhost/*discourse**。

此后,应用程序虽然上线了,但出现了许多问题:

  1. 所有静态内容(插件、资源、图片、JavaScript、上传文件)均无法访问。经过长时间的调试和无果的网页搜索后,我们在 Apache 中创建了一些代理规则,将这些内容隧道传输到 localhost 路径,不带 /discourse 前缀(例如,/discourse/plugins 指向 → unix:/../../nginx.http.sock|http://localhost/plugins,以此类推)。

  2. 某些 /uploads 路径来自网页时没有 /discourse 前缀,因此我们需要编写另一个 Apache 代理规则,将 /uploads/ 路径重定向到 *unix:/../../nginx.http.sock|http://localhost/discourse/uploads*。

  3. 最奇怪的是:当客户端发送包含 /uploads/default//discourse/uploads/default/(静态内容)的请求时,我们需要按照第 1 点所述的解决方案,将两者都重定向到 http://localhost/uploads/default/不带 /discourse 前缀);而其他不包含 /default 路径前缀的 /uploads//discourse/uploads/ 请求(即 Web 服务调用)则必须重定向到 http://localhost/discourse/uploads/

通过添加这 9 条代理规则,一切在 /discourse 路径下又正常运行了。但我们觉得非常奇怪,竟然需要编写这么多配置才能让一切正常工作。

我们是否做错了什么?
是否有更聪明的方法来处理这种情况?

=== 编辑 ===
忘记提到另一个可能相关的问题:
当用户尝试上传自定义图片作为个人头像时,上传成功,缩略图也能正确显示。

但点击“保存更改”按钮并重新加载页面后,头像又恢复为默认用户头像


检查 production.log 文件,发现错误代码为 418
其他图片上传功能正常。

提前感谢您的回复,也感谢你们出色的工作!

子文件夹安装要复杂得多,因此不推荐。

明白了,谢谢。

但在这种情况下我们似乎没有机会,所以如果没有其他建议,我们将持续监控情况,看看是否有其他代理规则可以管理。

关于用户上传的内容,您有什么建议吗?这看起来像是数据库存储问题,不是吗?