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.
The Problem
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.
The Solution
Setup a yaml file similar to this:
Add the following to config/application.rb
before the Rails application class
is defined:
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.
Note: Since application.yml
will typically hold passwords and other secret
keys, it should be added to .gitignore
so they don’t end up in source
control.
Now, when the application is initialized, PUSHER_URL
is
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://asdfa@api.pusherapp.com
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 config/application.yml
file on to the system. This is no different than using a database.yml
that
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.