五年前,本部落格第一篇文章就是在講使用 Settingslogic 作設定。經過了漫長的歲月,終於想到了怎樣還能作的更好,最後作出了一個新的 gem 叫做 Settei 。這是一個使用 yaml,但是又能符合 12-factor app 的設定方式。

https://github.com/lulalala/settei

緣起

12-factor app 是一套讓部屬更容易的規則。其中第三點指到,要把設定跟程式分開,並把設定存在環境(變數)中。

但是使用環境變數有很多缺點,要是你的程式有30項大大小小的設定,光是命名變數名稱就會很麻煩:

# 傳統使用 ENV 就得寫一長串超累:
BOARD_PAGINATION_PER_PAGE=5
BOARD_PAGINATION_MAX_PAGE=10
BOARD_REPLY_OMIT_CONDITION_N_RECENT_ONLY=5
BOARD_REPLY_OMIT_CONDITION_AVOID_ONLY_N_HIDDEN=2

使用YAML 就簡單很多

board:
  pagination:
    per_page: 5
    max_page: 10
  reply_omit_condition:
    n_recent_only: 5
    avoid_only_n_hidden: 2

但是要怎樣結合 YAML 的優勢跟 ENV VAR 的優勢呢?

我的想法是:把 YAML 給 serialize 成一串文字,就能當 env var 傳到遠端了。

本機開發跟遠端部屬的兩個流程如下:

settei.png

安裝

用 Gemfile 安裝以後:

gem 'settei'

在 rails 專案下執行以下 rake task 繼續安裝:

$ rake settei:install:rails

使用方法

要是 config/environments/default.yml 內容是這樣的話:

the_answer_to_life_the_universe_and_everything: 42
google:
  api: foo

就能這樣取得設定

Setting.dig(:the_answer_to_life_the_universe_and_everything)
Setting.dig(:google, :api)

部署

要是你是使用 capistrano 或是 mina 的話,應該自動會有效。我塞了一個設定,所以deploy時,你的production.yml會直接變成Env var隨著遠端的 Rails server 啟動。於是遠端的 server 也就拿到了設定。

要是你是使用 heroku 的話,使用 rake settei:heroku:config:set app=[app_name] 來把 production.yml 上傳到指定的app中。

更詳盡的使用方法請閱讀 github,也歡迎指教~~