19

I have 2 environments, production and staging, and I am using Capistrano with capistrano-ext gem.

When I deploy to staging using Capistrano and restart passenger, I would like the deployed application to run in staging however it runs in the default production

I tried setting:

set :rails_env, "staging"

in my deploy recipe, but this had no effect.

I am aware this can be done by setting a virtual host in Apache, but I am using shared hosting, so don't have access. My host offers this advice:

add the following to environment.rb: ENV['RAILS_ENV'] = 'staging'

but this doesn't help me automate the process with Capistrano.

ecoologic
  • 10,202
  • 3
  • 62
  • 66
dangerousdave
  • 6,331
  • 8
  • 45
  • 62
  • Is adding `ENV['RAILS_ENV'] = 'staging'` itself works? If it works, then it's just a matter of writing a Capistrano recipe to automate that. – htanata Aug 16 '11 at 04:01
  • Have you tried asking your hosting company to change the environment for you? That is the best way to solve this. If they refuse to cooperate you can draw your conclusions about them. – Martijn Aug 16 '11 at 07:39
  • @htanata - Yes that works, ill look into automating that from Capistrano, thanks. – dangerousdave Aug 17 '11 at 08:39

4 Answers4

16

What you are doing when you setting :rails_env, "staging" environment is setting the environment for the migration. In other words, it's a environment that is only set when you're running capistrano. If I understand you correctly, you want to change the environment when running your app, not deploying.

In order to answer your question, I'll need to know how you are launching (starting) your application.

If you're using Phusion Passenger, you'll need to edit your RAILS_ENV for Passenger

Given that you're in a shared environment, you'll probably want to go with the .htaccess route.

fotanus
  • 19,618
  • 13
  • 77
  • 111
Cory
  • 5,645
  • 3
  • 28
  • 30
  • I don't start it as such, phusion passenger handles that. – dangerousdave Aug 17 '11 at 08:41
  • Ah, good to know. You'll need to edit your RAILS_ENV for Passenger. Read this: http://www.modrails.com/documentation/Users%20guide%20Apache.html#rails_env Given that you're in a shared environment, you'll probably want to go with the .htaccess route. – Cory Aug 17 '11 at 17:33
  • Thanks cory, you want to add that as an answer please? – pingu Aug 17 '11 at 18:29
  • Hi Pingu, I moved my reply to my answer. – Cory Aug 17 '11 at 23:35
2

The right way to solve this is to set the Rails environment in your Passenger config. Get your shared hosting provider to set this up for you. In Apache it's done with RailsEnv directive.

If you REALLY can't do that, you could consider putting a TERRIBLE HACK like this at the top of your Rails pre-initializer (config/preinitializer):

forced_environment = './config/force_environment'
if File.exists?(forced_environment)
  ENV['RAILS_ENV'] = File.new(forced_environment).readline.chomp
end

...which will set the environment before loading Rails to the string in that config/forced_environment file. For your stage server you could set 'stage' as the environment.

This is a terrible, terrible hack. Your mileage may vary.

Winfield
  • 18,985
  • 3
  • 52
  • 65
2

You can use a capistrano hook to create files on the server or symlink them in from e.g. shared/ when deploying.

For Rails 2.3:

On your web host, create the file shared/preinitializer.rb:

ENV['RAILS_ENV'] = 'staging'

Then add this to your Capfile (or possibly config/deploy.rb if you're using a newer version of capistrano with Rails 2.x:

after 'deploy:symlink', 'localize:copy_shared_configurations'
namespace :localize do
  desc 'copy shared configurations to current'
  task :copy_shared_configurations, :roles => [:app] do
    # I put database.yml here to keep deployed db credentials out of git
    %w[
      preinitializer.rb
    ].each do |f|
      run "ln -nsf #{shared_path}/#{f} #{current_path}/config/#{f}"
    end
  end
end

For Rails 3

Due to the changes in Rails 3's initialization sequence, config/preinitializer.rb is not loaded until after config/environment.rb is loaded. So for Rails 3, you want to modify config/environment.rb only on the server. You could do this with a similar setup like Rails 2 above, but using a symlinked copy of config/environment.rb, and adding the step of deleting the existing file before trying to symlink.

Another option would be to overwrite the environment.rb on the server from capistrano. In your config/deploy.rb:

after 'deploy:symlink', 'localize:munge_environment'
namespace :localize do
  desc 'munge environment.rb to set staging environment'
  task :munge_environment, :roles => [:app] do
    new_env = "ENV['RAILS_ENV'] = 'staging'\n" + File.read(Rails.root.join('config', 'environment.rb'))
    put new_env, "#{current_path}/config/environment.rb"
  end
end
Jeremy Weathers
  • 2,556
  • 1
  • 16
  • 24
-2

What you need is the environment directive in your nginx configuration. If you are using Apache, there should be a similar directive there. (should be easy to google)

server {
        listen                  80;
        passenger_enabled       on;
        rails_env               staging;
        server_name             foo.com;
        root                    /your/app/path;

}

You cannot toggle this with just capistrano.

Tanel Suurhans
  • 1,632
  • 12
  • 11
  • 1
    Says he's using shared hosting. Cannot change it. – Ryan Bigg Aug 14 '11 at 10:16
  • What's the point of set :rails_env in capistrano if it does nothing? – pingu Aug 14 '11 at 10:29
  • Using `set :rails_env` simply ensures that on tasks which require it there is a command prepended such as `RAILS_ENV=#{rails_env} rake db:migrate`. – Lee Hambley Aug 16 '11 at 12:47
  • 1
    Should be made clear that this is not a valid answer for this question yet it was the answer in my non shared hosting situation. – Antzi Aug 29 '14 at 08:59