雖然設置環境變數,都用 dotenv 很習慣了,不過 Rails 5.1 開始有針對這個問題討論一些解法,一開始拆兩支檔案 secrets.yml
和secrets.yml.enc
引起一些混亂
在 5.2 版本之後只有 credentials.yml.enc
加密憑證
要使用加密憑證,必須有一把密鑰,如果沒有密鑰將無法解密其內容,現在建立一個 5.2 版本以上的 rails project 時,會創建一支 matser key 放置於 config/master.key
並且很貼心的在 .gitignore
中加入忽略清單,可以避免不小心把 master.key commit 出去。
How to edit your credentials
EDITOR=vim rails credentials:edit
舉例來說
aws:
access_key_id: 123
secret_access_key: 345
保存之後,加密的版本將會存放在 config/credentials.yml.enc
,並且跟著 commit 進去。
在 Rails 裡面呼叫的方式
Rails.application.credentials.aws[:access_key_id]
Rails.application.credentials.aws[:secret_access_key]
或是透過 command line 顯示
rails credentials:show
確保 production 有設置開啟(預設是關閉的)
config.require_master_key = true
這樣做的好處是,我只要在機器上設定好一樣的 master.kry,每次部屬時都可以直接吃到新的環境變量。
因為在以往的作法,必須確保在部屬前已經設定好環境變量,可能要手動去設定之類的,現在這個作法可以省掉這一道功夫。
只要確保機器上 copy 的 master.key 副本跟編輯時用的是同一把即可。
這樣的好處同時也讓所有的環境變量保存在一個檔案中,更集中管理。
不過也遇到一些問題,比方說 production 和 staging 上要用的 key 不一樣…
你總不會想要寫
production:
aws:
access_key_id: 123
secret_access_key: 345
staging:
aws:
access_key_id: abc
secret_access_key: def
然後依照環境判斷分別呼叫?
Rails.env.production? ? Rails.application.credentials.production[:aws][:secret_access_key] : Rails.application.credentials.staging[:aws][:secret_access_key].
或是加載不同的 master.key? (這樣也還要重新生成不同的加密結果, commit 裡面那隻可能也不能用了 XD)
RAILS_ENV=production RAILS_MASTER_KEY=content_of_master.key rails server
太麻煩了…,在 Ruby China 也有提到關於 Rails 5.2 的新 secret credentials 怎样让不同的环境使用不同的配置?
但目前還沒有一個比較整合的作法,正常來講應該要依照不同環境的需求有不同的環境變數,rails 6 看來在著手解決這個問題。
Add support for multi environment credentials.
結論
還是先用 dotenv 並觀望 rails 6 能不能解決這個問題 XD