※ Erlang勉強しはじめたばかりなのでベストプラクティスではないかもしれません
モチベーション
Erlangプロジェクトで、外部リソースを参照する必要があり環境ごとにエンドポイント設定を変えたい…という場合があります。
例えば、Erlangアプリケーションから外部Redisを参照するような場合です。
{ok, RedisHost} = application:get_env(my_application, redis_host).
ベタ書きでホスト情報をコード中に書いていくのではなく、上記のように、アプリケーションのコードから動的にホスト情報を取得したいです。
rebar3で環境ごとのapplication environment variableを設定する
rebar3のProfileについて
rebar3にはProfileという機能があります。以下のようなことが簡単にできます。
-
rebar.config
に任意の設定をprofile名とひもづけて書いておくことができる -
rebar3
コマンドにrebar3 as <profile> <command>
のような形式でprofile名を与え、任意のprofile設定をコマンド実行時に適用することができる
rebar3では内部でrelxを利用してリリースパッケージを作成しています。また、rebar.config
内にrelxのconfigをそのまま書くことができます。
relxのconfigにはsys_config
というものがあり(configuration · erlware/relx Wiki)、ここではerl -config <config>
のconfig fileとして指定するファイルパスを設定することができます。
(※Erlangのconfig設定についてはこちらを参照しました Erlang -- config)
この機能を利用して、以下のようにすれば環境ごとの変数設定ができそうです。
- 環境ごとにconfig fileを用意する
- 環境ごとにrebar3のProfileを用意する
-
rebar.config
内でProfile設定ごとにconfig fileを切り替えるような設定をする
rebar.configでProfile設定を追加する例
下記のように環境毎のconfig fileを用意します。
%% config/sys.config
[
{my_application, [
{redis_host, "127.0.0.1"}
]}
].
%% config/sys.config.production
[
{my_application, [
{redis_host, "10.0.0.1"}
]}
].
rebar.config
では、production
というProfile設定を追加します。Prodile設定production
以下にrelxのsys_config設定を追加します。
%% rebar.config
%% ... 省略
{relx, [
{release,
{my_application, "0.0.1"},
[my_application, sasl]},
{dev_mode, true},
{include_erts, false},
{vm_args, "./config/vm.args"},
{sys_config, "./config/sys.config"}, %% 開発環境用のsys.config
{extended_start_script, true}
]}.
{profiles, [
%% ※必要に応じてdefault profile設定を追加
{production, [
{relx, [
{dev_mode, false},
{sys_config, "./config/sys.config.production"} %% 本番環境用のsys.config
]}
]}
]}.
Profileで設定した項目の優先順ですが、2016/06/29現在ドキュメントでは下記のように説明されています。
- Profile設定の
default
-
REBAR_PROFILE
環境変数 -
as
で指定されたProfile - rebar3コマンド設定で指定されたProfile設定
上記のrebar.configでは、標準のrelxの設定を書いたうえでproduction環境用のProfile設定を書いています。
production環境用のリリースパッケージを作る場合はrebar3 as production release
コマンドを使えば、rebar3がrelxのsys_config設定として./config/sys.config.production
を参照してくれます。
今回の例だと、rebar3 as production release
してできたリリースパッケージ中のコードで{ok, RedisHost} = application:get_env(my_application, redis_host)
すると、Redishost
は10.0.0.1
となります。
rebar3を使ってリリースパッケージを作成
前述したように、production環境用のリリースパッケージはrebar3 as production release
で作成することができます。
今回の例ではProfileをproduction
しか用意していませんが、rebar.configにdevelopment
, test
などのProfile設定を追加しておくと環境ごとに細かく設定を切り替えることができるので便利そうです。