Reputation: 113
I have a rails app which is set up to deploy with Capistrano to one of two different servers (depending on which the user chooses to deploy to). I want to create an environment variable for the rails app which changes depending on which server the website is deployed to.
In my Capistrano deploy (config/deploy.rb) file, I have a variable "stages" that has the two options for the user to deploy to:
set :stages, %w(production staging)
I have tried to use this variable in an if statement in my environment (config/environment.rb) file to set the variable like so:
if (:stages == "staging")
ENV['GLOBAL_EMAIL'] = "[email protected]"
else
ENV['GLOBAL_EMAIL'] = "[email protected]"
end
However, when I test this, rails fails to render #{ENV['GLOBAL_EMAIL']}
(as far as I can tell because the variable is not set or reachable.
My question is if there is a reason that :stages is not reachable, and also if there is a way/better way to set the variable according to the environment?
Note that even though one is called staging and one is called production, both environments deploy the production environment of rails (not test and production environments of rails), thus I cannot do a test to see which environment rails is running to then set the variable.
Upvotes: 0
Views: 1876
Reputation: 5616
For starters you are trying to equate a symbol with a string, which will always return false.
Also within capistrano, to get the environment your deploying in you want the stage
variable. This variable is only available after loading and not when the file is read by ruby. What this means is that you need to provide a block that gets lazy loaded. The problem is that these are evaluated in the context of setting a local variable such as deploy_to
.
set(:deploy_to) { "/var/www/#{application}/#{stage}" }
This is a common setup within my deploy scripts where staging and production are deployed to the same server.
You could possibly try something like:
set(:global_email) do
if stage == 'production'
ENV['GLOBAL_EMAIL'] = '[email protected]'
else
ENV['GLOBAL_EMAIL'] = '[email protected]'
end
end
Or another way of handling this is to use the deploy stage specific files.
# config/deploy/production.rb
ENV['GLOBAL_EMAIL'] = '[email protected]'
# config/deploy/staging.rb
ENV['GLOBAL_EMAIL'] = '[email protected]'
I hadn't noticed the question mentioned rendering the value in Rails. This of course has nothing to do with Rails, nor is anything set in a Capistrano config file available when Rails is initialized since capistrano should really be only available in development environments.
A proper way to do this would be using a rails initalizer and setting the variable when Rails boots up.
# config/initializer/global_email.rb
if Rails.env.production?
GLOBAL_EMAIL = '[email protected]'
else
GLOBAL_EMAIL = '[email protected]'
end
Upvotes: 3
Reputation: 113
The final solution I ended up with was to create a file external from my Capistrano deploy (for instance in /home/[user]/.var/.emails) on each server where each file contains just the desired email (e.g. [email protected]
). Then in environments.rb:
ENV['GLOBAL_EMAIL'] = begin IO.read("/home/[user]/.vars/.email") rescue "" end
Upvotes: 0