【问题标题】:Duplication of context in path for a Rails app on TorqueBox with Apache ReverseProxy使用 Apache ReverseProxy 在 TorqueBox 上的 Rails 应用程序的路径中重复上下文
【发布时间】:2014-06-13 23:17:19
【问题描述】:

我在一个场景中苦苦挣扎,我有多个应用程序要在单个 TorqueBox 实例上运行。在定义应用程序并将其部署到 config/torquebox.yml 中的根 ("/") 上下文时,应用程序可以正常执行,没有明显问题。起初我认为这是 Apache 反向代理的问题,但现在认为这可能是 Rails 和/或 TorqueBox 的问题,但我找不到明确的答案或问题的原因。

这个配置如下:

config/torquebox.yml 包含:

web:
  context: /

Apache 的代理 httpd 虚拟主机配置是:

ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/

有了这个我可以访问http://sub.domain.tld/postsposts/new 路由就好了。这是通过大致遵循the example here(我执行的唯一修改是使反向代理工作的那些)。

但是当我换档并在torquebox_test_rails_production 的上下文中运行它时,事情开始变得非常奇怪。我不得不相信,由于某种原因,rails 会将上下文的副本附加到路径上,这是有问题的。解释:

我把config/torquebox.yml改成:

web:
  context: /torquebox_test_rails_production

和 Apache 的 httpd 虚拟主机 conf 到:

ProxyPass / http://127.0.0.1:8080/torquebox_test_rails_production/
ProxyPassReverse / http://127.0.0.1:8080/torquebox_test_rails_production/

当我这样做时,http://sub.domain.tld/ 仍然可以正常加载,但是当我转到 posts 时,我注意到(在 log/production.log 中)一个失败的 GET 请求:

INFO -- : Started GET "/torquebox_test_rails_production/torquebox_test_rails_production/stylesheets/application.css"
FATAL -- : 
ActionController::RoutingError (No route matches [GET] "/torquebox_test_rails_production/stylesheets/application.css"):
  actionpack (4.1.1) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
  actionpack (4.1.1) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
  railties (4.1.1) lib/rails/rack/logger.rb:38:in `call_app'
  railties (4.1.1) lib/rails/rack/logger.rb:20:in `call'
  activesupport (4.1.1) lib/active_support/tagged_logging.rb:68:in `tagged'
  activesupport (4.1.1) lib/active_support/tagged_logging.rb:26:in `tagged'
  activesupport (4.1.1) lib/active_support/tagged_logging.rb:68:in `tagged'
  railties (4.1.1) lib/rails/rack/logger.rb:20:in `call'
  actionpack (4.1.1) lib/action_dispatch/middleware/request_id.rb:21:in `call'
  rack (1.5.2) lib/rack/methodoverride.rb:21:in `call'
  rack (1.5.2) lib/rack/runtime.rb:17:in `call'
  rack (1.5.2) lib/rack/sendfile.rb:112:in `call'
  railties (4.1.1) lib/rails/engine.rb:514:in `call'
  railties (4.1.1) lib/rails/application.rb:144:in `call'

如您所见,它复制了路径上的上下文。

此时 URL 仍然正确,只需 http://sub.domain.tld/posts,但是当我在脚手架测试中单击“新帖子”时,应用程序会尝试将浏览器重定向到 http://sub.domain.tld/torquebox_test_rails_production/posts/new。显然这种重定向/重复不应该发生。在我现在看到的日志中:

INFO -- : Started GET "/torquebox_test_rails_production/torquebox_test_rails_production/posts/new"
FATAL -- : 
ActionController::RoutingError (No route matches [GET] "/torquebox_test_rails_production/posts/new"):
  actionpack (4.1.1) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
  actionpack (4.1.1) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
  railties (4.1.1) lib/rails/rack/logger.rb:38:in `call_app'
  railties (4.1.1) lib/rails/rack/logger.rb:20:in `call'
  activesupport (4.1.1) lib/active_support/tagged_logging.rb:68:in `tagged'
  activesupport (4.1.1) lib/active_support/tagged_logging.rb:26:in `tagged'
  activesupport (4.1.1) lib/active_support/tagged_logging.rb:68:in `tagged'
  railties (4.1.1) lib/rails/rack/logger.rb:20:in `call'
  actionpack (4.1.1) lib/action_dispatch/middleware/request_id.rb:21:in `call'
  rack (1.5.2) lib/rack/methodoverride.rb:21:in `call'
  rack (1.5.2) lib/rack/runtime.rb:17:in `call'
  rack (1.5.2) lib/rack/sendfile.rb:112:in `call'
  railties (4.1.1) lib/rails/engine.rb:514:in `call'
  railties (4.1.1) lib/rails/application.rb:144:in `call'

我在这里尝试的另一件事是将config.relative_url_root 添加到配置中。我通过尝试以下环境变量来做到这一点:

RAILS_RELATIVE_URL_ROOT="/torquebox_test_rails_production"

并在config/environments/production.rb 中设置为:

config.relative_url_root = "/torquebox_test_rails_production"

我认为这应该通过上下文设置自行设置,因此它的目的是,但我认为值得一试。

我还从this question 那里得到了提示,这似乎与我的相同,但是从torquebox.yml 中删除context 并且仅使用主机名也不能解决问题。相反,它似乎已经消除了路径上下文的加倍,但我最终在log/production.log 中仍然出现以下错误:

INFO -- : Started GET "/torquebox_test_rails_production/posts"
FATAL -- : 
ActionController::RoutingError (No route matches [GET] "/torquebox_test_rails_production/posts"):
  actionpack (4.1.1) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
  actionpack (4.1.1) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
  railties (4.1.1) lib/rails/rack/logger.rb:38:in `call_app'
  railties (4.1.1) lib/rails/rack/logger.rb:20:in `call'
  activesupport (4.1.1) lib/active_support/tagged_logging.rb:68:in `tagged'
  activesupport (4.1.1) lib/active_support/tagged_logging.rb:26:in `tagged'
  activesupport (4.1.1) lib/active_support/tagged_logging.rb:68:in `tagged'
  railties (4.1.1) lib/rails/rack/logger.rb:20:in `call'
  actionpack (4.1.1) lib/action_dispatch/middleware/request_id.rb:21:in `call'
  rack (1.5.2) lib/rack/methodoverride.rb:21:in `call'
  rack (1.5.2) lib/rack/runtime.rb:17:in `call'
  rack (1.5.2) lib/rack/sendfile.rb:112:in `call'
  railties (4.1.1) lib/rails/engine.rb:514:in `call'
  railties (4.1.1) lib/rails/application.rb:144:in `call'

然后,我还尝试在 production.rb 中定义 config.relative_url_root,如前所述,结果与刚才提到的错误完全相同。

您知道这里可能会发生什么来引发这种行为吗?

【问题讨论】:

  • 不要将 Apache 用于代理 - 尝试使用 Nginx。它就是出于这个原因而创建的,并且性能比 Apache 更好。见这里:serverfault.com/questions/143238/…
  • @DamienRoche Nginx 不是这种情况的选择,但感谢您的建议。如果它是一个选项,我肯定会使用它。此外,它使用的是 httpd 2.4,因此无论如何它现在都与 nginx 相当。
  • 真可惜。无论如何,祝你好运。

标签: ruby-on-rails ruby apache ruby-on-rails-4 torquebox


【解决方案1】:

我没有方便测试的 Apache 配置,但您是否在 ProxyPass 和 ProxyPassReverse 中有一个斜杠,但在您的 Torquebox.yml 的 Web 上下文中没有?

所以不是

ProxyPass / http://127.0.0.1:8080/torquebox_test_rails_production/
ProxyPassReverse / http://127.0.0.1:8080/torquebox_test_rails_production/

试试

ProxyPass / http://127.0.0.1:8080/torquebox_test_rails_production
ProxyPassReverse / http://127.0.0.1:8080/torquebox_test_rails_production

【讨论】:

  • 不幸的是,在config/torquebox.yml 的上下文中添加尾随“/”仍然具有相同的行为。当我从 proxypas url arg remove 后缀“/”时,我最终让 apache 立即将上下文添加到 url,并在我的访问日志中为该站点添加 404。根据昨天在 IRC 中 thumbs 的某些指示,结尾的“/”基本上应该始终用于 httpd 反向代理传递配置。
【解决方案2】:

这里的解决方案是我需要将根上下文(“/”)与主机定义一起使用,然后从 mod_proxy 配置中删除上下文。

因此,最后,config/torquebox.yml 中的以下内容起作用:

web:
  context: /
  host: sub.domain.tld

以及虚拟主机的 httpd mod_proxy 部分中的以下内容:

<Location />
    ProxyPass http://127.0.0.1:8080/
    ProxyPassReverse http://127.0.0.1:8080/
</Location>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-04
    • 2018-11-27
    • 2011-04-23
    • 1970-01-01
    • 2011-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多