NodeConfig
Simple "node" configuration solution for Rails applications.
Prelude
"node" is a single machine, which your Rails application is running on. So "node" configuration is the configuration for that specific machine. For example:
- Your development laptop is also a "node" and needs a local configuration for development.
- Your server is also a "node", but it needs a different configuration for production.
Purpose
We need to maintain lots of configuration keys specific for a "node", like AWS access keys, Google-Analytics keys and much more...
Also:
- We want all of this keys to be defined in a single file
- We want all of this keys to be loaded automatically on Rails startup
- We want all of this keys to be available inside Rails application
- We want that a missing key results in a descriptive error
- We want this keys to be loaded into a process, which doesn't load the whole application
This is what NodeConfig
tries to simplify.
Installation
# Gemfile
gem("node_config")
$ bundle install # Install the gem
$ rails generate node_config # Generate configuration files
Usage
Put your node configuration into generated RAILS_ROOT/config/node_config.yml
.
Within a loaded Rails application
Your node configuration is available in Rails application config.
This is done by the generated initializer config/initializers/node_config.rb
.
# config/node_config.yml
foo:
bar: :baz
# rails console
Rails.application.config.node_config.foo #=> {"bar" => :baz}
Rails.application.config.node_config.foo. #=> :baz
In a Rake task:
# Rakefile
task :my_task do
puts(Rails.application.config.node_config.foo.) #=> baz
end
Using without loading Rails
Outside the Rails you can access the node configuration through the top level module named as your Rails application:
PetShop.node_config.foo. #=> :baz
This is done by loading the generated RAILS_ROOT/config/node_config.rb
.
If you have a Rake task for which the node configuration should be available without loading whole Rails, use the generated shortcut task.
# lib/tasks/my_task_which_doesnt_need_rails.rake
load File.("../node_config.rake", __FILE__)
task :my_task_which_doesnt_need_rails => :node_config do
puts(PetShop.node_config.foo.) #=> baz
end
Or as command line in your Procfile
(https://github.com/ddollar/foreman)
for a worker (https://github.com/defunkt/resque):
# Rakefile
load File.("../lib/tasks/node_config.rake", __FILE__)
worker: bundle exec rake node_config resque:work
If you have a script for which the node configuration should be available without loading whole Rails, be aware that the process has to be bundled. Otherwise it may not find the gem.
For example in your backup script (https://github.com/meskyanichi/backup):
# config/backup.rb
require File.("../node_config", __FILE__)
PetShop.node_config.foo. #=> :baz
Same when deploying with Capistrano (https://github.com/capistrano/capistrano):
# config/deploy.rb
require File.("../node_config", __FILE__)
PetShop.node_config.foo. #=> :baz
Or even in an external Ruby script:
# foo.rb
require "/srv/www/pet_shop/current/config/node_config"
PetShop.node_config.foo. #=> :baz
If you have a process, which isn't bundled, then require the gem manually:
# foo.rb
require "rubygems"
require "node_config"
require "/srv/www/pet_shop/current/config/node_config"
PetShop.node_config.foo. #=> :baz
Errors
Under the hood NodeConfig
uses HashWithStructAccess
,
so a missing key will result in appropriate NoMethodError
(see https://github.com/kostia/hash_with_struct_access for details).
Using with Git
Of course you have instruct Git to ignore config/node.yml
.
But it's a good practice to maintain a configuration template with the list of required keys,
for example in config/node.yml.template
.