During my recent adventure of setting up a production server for my rails applications, I stumbled upon some strange behavior where if I typed in a non-existent route or caused rails to barf all over itself, it would still show me a debug stack trace instead of the 400.html or 500.html living in /public
I uncommented the ENV[‘RAILS_ENV’] ||= ‘production’ line in /config/environment.rb, and the behavior persisted. I created a controller and view to echo out the environment, and did confirm that the app is running in production mode.
Googling only led to minor success where it was alluded in 1 or 2 posts that rails might think it is still running locally.
I started to eye my Apache mod_proxy_balancer + mongrel_cluster arrangement, where the cluster is set to spawn instances on 127.0.0.1 (localhost). After changing that local address to the outside facing address (192.168.x.x) and accessing it at that address in my vhost conf. Things were working as expected.
Now why would rails act this way? Searching the Rails API led me to the rescue_action and rescue_action_in_public methods, which led me to the local_request? method of determining which of the previous methods get called.
Great, now I’ve found the culprit. The code looks like the below:
# from rescue_action if consider_all_requests_local || local_request? rescue_action_locally(exception) else rescue_action_in_public(exception) end #local_request? def local_request? request.remote_addr == LOCALHOST and request.remote_ip == LOCALHOST end
An easy fix is to drop a method that overrides this in application.rb
def local_request? return false if RAILS_ENV == 'production' end
So, if you are having trouble making your app behave like its in production mode, give it a little spanking and remind it not to trust strangers with its debug trace.