mod_rails set RAILS_ENV variable to QA, Staging, or Production

I’m using mod_rails with capistrano and multi-stage (qa, staging, production), and wrote this workaround so that the RAILS_ENV could be set correctly in each stage.  Mod_rails sets RAILS_ENV once in the global server conf file, but I needed it set once for each environment: qa, staging, and production.  I tried setting ENV['RAILS_ENV] in each file under config/deploy/ but the setting was not picked up.

Solution - write the correct value into config/environment.rb’s  ENV[''RAILS_ENV] while deploying.

So here is my 3 step fix -

Step 1.

I created a new file

lib/set_mod_rails_env.rb

# sets ENV['rails_env'] for mod_rails
# http://www.megasolutions.net/ruby/search-a-file-and-replace-text-50116.aspx
# Robert Evans'
def ChangeOnFile(file, regex_to_find, text_to_put_in_place)
  text = File.read file
  File.open(file, 'w+'){|f| f << text.gsub(regex_to_find,
      text_to_put_in_place)}
end
ChangeOnFile("#{ARGV[0]}/config/environment.rb", /#mod_rails_env_here/, "ENV['RAILS_ENV']='#{ARGV[1]}'")

Step 2.

Add the following code to config/deploy.rb

namespace :deploy do
desc "set ENV['RAILS_ENV'] for mod_rails"
task :before_restart do
run "ruby #{current_release}/lib/set_mod_rails_env.rb  #{current_release}  #{stage}"
end
end

Step 3.

Add the following code to config/environment.rb

# deploy.rb will swap this out for the appropriate rails_env.
# mod_rails apparently need this var in this file (not ./environments/qa.rb)
# do not change the following line. Ruby regexp looks for it.
#mod_rails_env_here

That’s it.  Let me know if you know of an easier way.

May 23, 2008 • Tags:  • Posted in: rails

3 Responses to “mod_rails set RAILS_ENV variable to QA, Staging, or Production”

  1. Andrew Vit - August 22, 2008

    Thanks! I just saw your answer to my question in the dreamhost forums from back in May… I’ve already set up something similar, except I’m skipping the regex & extra rb file for a simple solution all in my deploy.rb file. It just prefixes the file with the RAILS_ENV using cat:

    after "deploy:finalize_update", "deploy:set_rails_env"

    namespace :deploy do
    task :set_rails_env do
    tmp = "#{current_release}/tmp/environment.rb"
    final = "#{current_release}/config/environment.rb"
    run <<-BASH
    echo 'RAILS_ENV = "#{rails_env}"' > #{tmp};
    cat #{final} >> #{tmp} && mv #{tmp} #{final};
    BASH
    end
    end

  2. Owen - November 1, 2008

    I just used this and it was a huge help!

  3. Unirec - December 8, 2008

    After trying every other method I could find, I added Andrew’s solution to my ‘witches brew’ - works great. Thanks!

    [I can't believe this hack is required to set up a simple staging environment (in a multistage system). I got into Rails to try to avoid this kind of BS...]

Leave a Reply