Flexible Rails Environment Configuration
It’s hard to write a Rails app without interfacing with an external service or API. In most cases, these services require a secret token or password. Since checking passwords in to source control is generally a bad practice, we need a good way to safely and reliably access these values in code.
I’ve tried a few gems that attempt to make this process easier and ultimately settled on a simpler solution – the combination of a few lines of code and ENV variables, which are accessible whether you manage your own infrastructure or use a PaaS service like Heroku.
In a recent Rails app, I used Pusher and it requires the unique URL to be setup in an initializer:
If I need to set this URL in multiple place – copying/pasting is not a great solution because it sets me up for copy/paste errors. It’s also a headache to find all occurrences of the URL when it changes.
Setup a yaml file similar to this:
Add the following to
config/application.rb before the Rails application class
Resulting in a
config/application.rb that looks something like this:
The added code first looks for an
application.yml file. If it finds one, it
reads in the values for that environment (development, test, production, etc.)
and merges them in to the existing Ruby ENV hash.
application.yml will typically hold passwords and other secret
keys, it should be added to
.gitignore so they don’t end up in source
Now, when the application is initialized,
available in the ENV hash. This allows me to the update the pusher initializer to:
If I’m deploying to Heroku, I need to set the config value using the following command:
heroku config:set PUSHER_URL=http://firstname.lastname@example.org
Or if I’m deploying to Ubuntu, I can set the ENV variable for all users on the system:
Note: If you choose not to set ENV variables on the host system, you can
easily mimic the development environment and drop the
file on to the system. This is no different than using a
most Rails developers are used to.
That’s it! So with 7 lines of code and a configuration file, you have yourself an environment configuration setup that’s flexible for most deployment solutions.