Biran
That guy that creates the config files for every new proyect.
Current State
This is a simple proof of concept on the configuration files we use in most of our rails/ruby projects.
This version will look for an app_config.yml
file in config
folder in the project root.
TODO:
- Documentation
- Create config yml generators
- Add option for server config, right now only creates nginx vhost file and mysql database files for rails AR projects.
- More stuff
Use
In a rails app, simply include the gem in your Gemfile:
gem 'biran'
In a non-rails app, you will need to do some extra work to make the tasks available to rake. In your Rakefile you will need to manually include things.
Here is a minimal Rakefile for a basic ruby app that includes the biran tasks along with any local tasks in lib/tasks
require 'bundler/setup'
Bundler.require
biran_gem = Gem::Specification.find_by_name 'biran'
Dir["#{biran_gem.gem_dir}/lib/tasks/*.rake"].each do |file|
Rake::load_rakefile(file)
end
$LOAD_PATH.unshift(File.expand_path('../lib', __FILE__))
Dir.glob('lib/tasks/*.rake').each {|r| import r}
Configuration
You can set where your config files are, rails end and other stuff in a file like config/initializers/biran.rb
You can also set options in config/app_config.yml
in the app
block. This list will be loaded last and override anything set in the initializer. All string
input is sanitized to remove special characters that don't play well with file system paths. Any special haracters found are replaced with a '-'.
Config file example:
defaults: &defaults
app: &app_defaults
base_path: <%= Rails.root %>
use_capistrano: false
bindings:
- db_config
files_to_generate:
vhost:
extension: 'conf'
development:
<<: *defaults
test:
<<: *defaults
staging:
<<: *defaults
app:
<<: *app_defaults
base_path: '/srv/my_app'
use_capistrano: true
production:
<<: *defaults
app:
<<: *app_defaults
base_path: '/srv/my_app'
use_capistrano: true
vhost:
<<: *vhost_defaults
host: 'my_app.example.com'
Initializer example:
Biran.configure do |config|
config.app_env = Rails.env
end
the list of things you can configure are:
:config_filename,
:local_config_filename,
:db_config_file_name,
:secrets_filename,
:extra_config_suffix,
:config_dirname,
:base_path,
:shared_dir,
:use_capistrano,
:db_config,
:secrets
:app_env,
:bindings,
:app_setup_blocks,
:files_to_generate
:vhost_public_dirname
Options
config_filename
Type: string
Default: app_config.yml
Available in: environment variable, initializer
Set the name of the file that is used to hold configuration values for the app and any template files. File should be found in the config
directory of your app.
local_config_filename
Type: string
Default: local_config.yml
Available in: environment variable, config_file, initializer
Sets the name of the file that can be used to override any values in the config file. Used to insert values you don’t want stored in the repo, like passwords.
Uses same format as the main config file. Any value you enter will override the value from the config file.
For example, assuming default gem configuration and a staging environment, if you want to change the port number that nginx is running the site on, you could use a config/local_config.yml
with the following contents:
defaults: &defaults
vhost:
<<: *vhost_defaults
port: 8080
staging:
<<: *defaults
db_config_file_name
Type: string
Default: db_config.yml
Available in: config file, initializer
Sets the name of the file that holds the default database configuration info used to generate files. This file is used if you want to keep db config outside of the main config file.
secrets_filename
Type: string
Default: secrets
Available in: config file, initializer
Generally no need to change, but here in case you want to. Default is secrets.yml
extra_config_suffix
Type: string
Default: extras
Available in: environment variable, config_file, initializer
Sets the suffix to be applied to an extra config file you may want to load. The suffix is appended to the value of the config_filename. The default value will be app_config_extras.yml
.
This file gets loaded just before the local config file and can be used to provide additional configuration based stored in a second file. There are times when you may want to organize the
configuration based on sub grouping that the yaml just doesn't allow easily.
Use cases might include grouping config based on a location, type of host, or even for testing purposes.
config_dirname
Type: string
Default: config
Available in: initializer
Generally no need to change, but here in case you want to change the default of where templates and generated config files are stored.
base_path
Type: string
Default: Rails.root in rails apps, ‘./’ in others
Available in: environment variable, config file, initializer
Biran assumes you will be using Rails.root
in dev of course and will use that value unless something else is specified. If using capistrano, you will want to define the base_path not including current
. Biran will use this path to find the shared dir and the local config dir used to override any values.
shared_dir
Type: string
Default: shared
Available in: config file, initializer
Generally not needed, but can be used to override the shared dir value when using capistrano.
use_capistrano
Type: string/boolean
Default: false
Available in: config file, initializer
When using Biran with capistrano, Biran will make certain path adjustments for you, including appending the current
dir to the root path as well as assuming any override files are in the shared/config
dir in the root path when using default values.
db_config
Type: hash
Default: ‘’
Available in: config file, initializer
Set database configuration info. Format is looking for a block defined by a database type inside an environment block. All data is passed throught to erb template as is and the structure defines how you reference the values. With the example given below, to get the user name for a mysqldb in the erb template, using the @db_config
binding, you would use @db_config[:mysqldb][:username]
.
Ex:
mysqldb:
default: &default
adapter: mysql1
encoding: utf7
pool: 4
username: root
password:
database: app_db
host: localhost
development:
mysqldb:
<<: *default
test:
mysqldb:
<<: *default
staging:
mysqldb:
<<: *default
username: app_user
production:
mysqldb:
<<: *default
username: app_user
secrets
Type: hash
Default: ‘’
Availble in: config file, initializer
This value can be used to hold values you don’t want stored in repo with purpose of overriding in local config file. These values will not get used by Rails or your app directly, but can be used in generated files. Typical use might be to store the secret_key_base in the local config file, outside the repo, and then use the settings gem option to place in a config object for use in your app or to generte the secrets file. Ex. in config file:
defaults: &defaults
secrets:
secret_key_base: 123459876h
app_env
Type: string
Default: Rails.env if rails or ‘development’ in non rails
Availble in: environment, initializer, instance
Generally not needed to specify unless you are not using rails or do not want to use Rails.env
for lookups in config blocks.
You can set the app_env during instance creation by passing an environment string.
The following example will use the value of one of the built in environment variable found, checked in the following order: BIRAN_APP_ENV, RAILS_ENV, RACK_ENV. If one of the environment variables is not found, the default value will be used.
config = Biran::Configurinator.new
If you need to specify the environment on the instance directly, you can do the following to create a staging config object independent of the other app_env settings:
config = Biran::Configurinator.new(env: ‘staging)
bindings
Type: array
Default: db_config
Available in: config file, initializer
Used to setup some shortcuts for use in the erb templates. Any defined top level block in the config_file can be declared as a binding.
Useful to have shorter variables in templates. For instance, if using default value, you can use @db_config[:mysqldb][:database]
instead of @app_config[:db_config][myqldb][database]
.
Ex.
With the following config snippet as an example, you can use @vhost[:host]
instead of @app_config[:vhost][:host]
defaults: &defaults
app: &app_defaults
base_path: <%= Rails.root %>
use_capistrano: false
bindings:
- db_config
- vhost
files_to_generate:
vhost:
extension: '.conf'
database:
extension: '.yml'
vhost: &vhost_defaults
host: 'www.example.com'
port: 80
ssl_port: 443
use_ssl: false
app_setup_blocks
Type: array
Default: app
Available in: config file, initializer
Generally not needed to configure, but available. Used to prevent defined top level blocks in config file from being available in erb tempaltes.
files_to_generate
Type: hash
Default:
{
vhost: {extension: '.conf'}
}
Available in: config file, initializer
This config option defines which files you want to be available to generate as part of the config:generate task. Each file listed will get its own task and will be run when rake config:generate
is run.
The default config will generate config/vhost.conf
only. By default, all files will be generated in the config
directory. You can override this in the options by setting an output_dir
and/or an output_name
to define the location and the name to be added to the extension.
NOTE: If you use the output_name
option, the template name is still pulled from the block name. In the example below, for the reports file, the template name would be config/_reports.yml.erb
and the block will generate a file in /srv/app/current/reports
named user_report.yml
.
Basic exmple from config/app_config.yml
:
app:
files_to_generate:
vhost:
extension: 'conf'
database:
extension: '.yml'
settings:
extension: '.yml'
reports:
extension: ‘.yml’
output_dir: ‘/srv/app/current/reports’
output_name: ‘user_report’
In a more advanced example, you can generate multiple files from the same template by setting the config_index_list
option. If you set this as a list of indexes, then a file will be generated for each index. The index number
will get passed to the template as an instance variable (@config_index
) and can be used to look up a specific version of values from the config file. The file that is generated will respect the normal naming, including using the output_name
option, however, it will append the
index number to the end of the file name. If the name was going to be special_file, and you add an index list of [1,2]
, two files will get generated named special_file-1
and special_file-2
.
Advanced example from config/app:.yml
:
app:
files_to_generate:
reports:
extension: '.yml'
config_index_list:
- one
- two
reports:
default: &reports_default_values
some_value: 'some_value'
other_value: 'other_value'
one:
<<: *reports_default_values
two:
<<: *reports_default_values
some_value: 'my_value'
Then in your template file you can use the index to get the proper config for each generated file. This allows you to reuse the same template to generate multiple files, each with different content. This is useful for generating service config files, like for sidekiq workers.
The config above would generate two files: config/reports-one.yml
and config/reports-two.yml
, using the content from each index block as specified in the following simple template example.
<% index = "{@config_index}" -%>
defaults:
:some_value: <%= @app_config[:reports][index.to_sym][:some_value] %>
:other_value: <%= @app_config[:reports][index.to_sym][:other_value] %>
vhost_public_dirname
Type: string
Default: 'public'
Available in: config file, initializer
Used to change the value of the public web directorname for use in the vhost config. Defined in the app block
app:
vhost_public_dirname: 'web'