Дублирование контекста в пути для приложения Rails на TorqueBox с Apache ReverseProxy

Я борюсь со сценарием, когда у меня есть несколько приложений для запуска на одном экземпляре 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/, с маршрутами posts и posts/new все в порядке. Это примерно соответствует примеру здесь (только те модификации, которые я выполнил, - это те, которые позволяют работать обратному прокси-серверу).

Но когда я переключаю передачи и запускаю его с контекстом torquebox_test_rails_production, все становится действительно странным. Мне остается верить, что что-то не так, когда рельсы по какой-то причине добавляют дубликат контекста к пути. Объяснить:

Я меняю config/torquebox.yml на:

web:
  context: /torquebox_test_rails_production

и конфигурация виртуального хоста Apache httpd для:

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 в конфигурацию. Я сделал это, попробовав переменную env:

RAILS_RELATIVE_URL_ROOT="/torquebox_test_rails_production"

и установив его в config/environments/production.rb на:

config.relative_url_root = "/torquebox_test_rails_production"

Я бы предположил, что это должно быть установлено через настройку контекста и, следовательно, его цель, но я подумал, что стоит попробовать.

Я также взял реплику из этот вопрос, который казался быть идентичным моему, но удаление context из torquebox.yml и просто наличие имени хоста также не решили проблему. Вместо этого, кажется, устранено удвоение контекста для пути, НО я все еще получаю следующую ошибку в 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'

Затем я также попытался определить config.relative_url_root в production.rb, как отмечалось ранее, с точно таким же результатом, как только что отмеченный с точки зрения ошибки.

Любая идея относительно того, что может происходить здесь, чтобы спровоцировать такое поведение?


person ylluminate    schedule 13.06.2014    source источник
comment
Не используйте Apache для прокси-серверов — вместо этого попробуйте Nginx. Он был создан по этой причине и работает лучше, чем Apache. См. здесь: serverfault.com/questions/143238/   -  person Damien Roche    schedule 14.06.2014
comment
@DamienRoche Nginx не подходит для этой ситуации, но спасибо за предложение. Я бы, конечно, использовал его, если бы это была опция. Кроме того, он использует httpd 2.4, так что теперь он фактически на одном уровне с nginx.   -  person ylluminate    schedule 14.06.2014
comment
Это позор. В любом случае удачи в поиске решения.   -  person Damien Roche    schedule 14.06.2014


Ответы (2)


У меня нет удобной конфигурации Apache для тестирования, но есть ли у вас завершающая косая черта в ваших ProxyPass и ProxyPassReverse, но не в вашем веб-контексте в вашем Torquebox.yml?

Итак, вместо

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
person earthtrip    schedule 13.06.2014
comment
К сожалению, добавление завершающего / в контекст config/torquebox.yml по-прежнему имеет идентичное поведение. Когда я удаляю постфикс / из аргумента URL-адреса proxypas, я получаю apache, немедленно добавляющий контекст к URL-адресу, и 404 в моих журналах доступа для этого сайта. В соответствии с каким-то указанием от thumbs вчера в IRC, завершающий / должен по существу всегда использоваться для конфигурации обратного прокси-сервера httpd. - person ylluminate; 14.06.2014

Решение здесь заключалось в том, что мне нужно было использовать корневой контекст ("/") с определением хоста, а затем удалить контекст из конфигурации 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>
person ylluminate    schedule 16.06.2014