Environment Variables in Ruby on Rails
Looking for ways to define variables
When you see configuration examples in README files of gems as shown below, what do you think they are?
Where should you define ENV['FOG_DIRECTORY']
? Should you define it in a shell script (such as ~/.bashrc
, ~/.bash_profile
, ~/.profile
, etc.) or in /etc/environment
? If you think so, I have to disappoint you—you are wrong!
Let’s define the FOG_DIRECTORY
variable in the ~/.bashrc
file. Pay attention if ~/.bashrc
includes the [ -z "$PS1" ] && return
line, otherwise you have to define the variables above it.
Then, reboot the shell and start a Ruby-on-Rails app. You will see that the app is configured correctly. You enjoy it and are going to deploy the app to production on VPS or VDS the same way. Everything is expected to work before the first reboot. Why ENV['FOG_DIRECTORY']
is nil
after server reboot? The answer is simple—nginx or another web server (I don’t know which one you use, but I prefer using nginx) starts before evaluating ~/.bashrc
and even /etc/environment
.
If you use assets_sync to upload your assets to the cloud, you can have an issue with Capistrano during deployment.
AssetSync: using default configuration from built-in initializer
rake aborted!
Fog provider can't be blank, Fog directory can't be blank
Tasks: TOP => assets:precompile:nondigest
(See full trace by running task with --trace)
So, we have to look for another way how to define these variables.
The solution
Considering the problem above, there is a reasonable question: what are these variables in the config and what to do? How should we define these variables? While surfing the Internet, I’ve found a good article that explains scenarios how to achieve our goals. Now, I will describe the scenario I think is much simpler and faster than others.
Insert the following lines of code to config/application.rb
after the config.assets.version = '1.0'
line.
Now, you have to create the yml
file in the config
folder and add it to .gitignore
if you have to define these variables locally. Key values are not real, so it doesn’t make sense to paste them in your configuration files. The example of config/local_env.yml
is shown below.
Finally, if we deploy the app with Capistrano, we have to deploy it properly. We should put local_env.yml
to the Capistrano
shared folder on the server and change config/deploy.rb
as exemplified below.
It is assumed that local_env.yml
exists in the {shared_path}/config/
folder on the server.
You have just explored how I’ve done the same thing with my database.yml
config (by the way, ignoring the database.yml
in your concurrent version system is a best practice, as well). The real-world example can be found in the README file of the awesome assets_sync gem.
Further reading
About the author
Andrey Koleshko is a Ruby developer at Altoros. He is majoring in delivering payment gateway solutions, as well as systems for billing, invoicing, subscriptions, bookkeeping, and accounting. Find him on GitHub.