リリースするアプリケーションでは、実行環境に依存する情報をコード内に抱え込まないように、環境変数から設定を取得することが多いと思います。
Elixir では設定情報を config/config.exs
に書くことが多いのですが、このファイルはビルド時に読み込まれるため、この中で環境変数の値を取り込んでも実行時に反映されません。
Elixir 1.9 では config の扱いが変わりました。
1.8 までは Mix.Config という Mix のモジュールを利用していましたが、1.9 からは Elixir が直接持つ Config というモジュールを利用するように変更されています。
また、実行環境に合わせた設定をアプリケーションが起動するタイミングでおこないたい、という動機で config/releases.exs
が導入されたようです。
アプリケーションをリリースする段になって混乱しないように Elixr 1.9 の config の使い方を確認してみました。
config/config.exs
まず従来からある config/config.exs
の挙動を確認してみます。
挙動を確認するためのプロジェクトを用意する
適当なプロジェクトを用意します。
$ mix new hoge
$ cd hoge
1.9 からは config の扱いが変更になったのにともない、 mix new
コマンドはディレクトリ config
および config ファイルを作成しなくなりました。
config が必要なばあいは自分でディレクトリ config
を作成します。
$ mkdir config
config.exs を記述する
config/config.exs
ファイルを作成して設定を記述します。
import Config config :hoge, foo: System.get_env("FOO"), bar: System.get_env("BAR")
挙動を確認するための関数を用意する
lib/hoge.ex
にアプリケーションの設定を表示する関数を追加します。
defmodule Hoge def show_env do IO.write("foo: ") IO.inspect(Application.fetch_env(:hoge, :foo)) IO.write("bar: ") IO.inspect(Application.fetch_env(:hoge, :bar)) end end
またリリース版を作成するために lib/hoge/application.ex
を用意します。
defmodule Hoge.Application do use Application def start(_, _) do # 環境変数を表示する関数を呼び出す Hoge.show_env() # 今回は実行を継続する必要がないので環境変数を表示したら終了する System.halt() end end
Hoge.Application
を callback module として設定します。
(最初の投稿時にこの記述が抜けていました。失礼しました)
defmodule Hoge.MixProject do # ... def application do [ extra_applications: [:logger], mod: {Hoge.Application, []} ] end # ... end
挙動を確認する
リリース版をビルドします。
$ mix release
実行します。
$ _build/dev/rel/hoge/bin/hoge start foo: {:ok, nil} bar: {:ok, nil}
環境変数を設定して実行します。
$ FOO=foo BAR=bar _build/dev/rel/hoge/bin/hoge start foo: {:ok, nil} bar: {:ok, nil}
実行時に環境変数を指定しても反映されません。
リリース版をビルドするときに環境変数を設定してみます。
$ FOO=foo BAR=bar mix release
実行します。
$ _build/dev/rel/hoge/bin/hoge start foo: {:ok, "foo"} bar: {:ok, "bar"}
環境変数を設定して実行します。
hoge $ FOO=hoge BAR=fuga _build/dev/rel/hoge/bin/hoge start foo: {:ok, "foo"} bar: {:ok, "bar"}
実行時の環境変数は影響を与えず、ビルド時に設定した値が表示されることがわかります。
config/releases.exs
次に config/releases.exs
を作成して設定を記述します。
releases.exs を記述する
import Config config :hoge, bar: System.get_env("BAR")
挙動を確認する
リリース版をビルドします。
$ mix release
実行します。
$ _build/dev/rel/hoge/bin/hoge start foo: {:ok, nil} bar: {:ok, nil}
環境変数を設定して実行します。
$ FOO=hoge BAR=fuga _build/dev/rel/hoge/bin/hoge start foo: {:ok, nil} bar: {:ok, "fuga"}
config/releases.exs
で環境変数を利用するようにした bar
は実行時の環境変数の値が反映されることがわかります。
次にビルド時に環境変数を設定します。
$ FOO=foo BAR=bar mix release
実行します。
$ _build/dev/rel/hoge/bin/hoge start foo: {:ok, "foo"} bar: {:ok, nil}
ビルド時に環境変数 BAR
にも値を設定しましたが、実行時に設定していないため bar
の値は nil
になっています。
またここから、 config.exs
と releases.exs
に同じ設定を記述したばあい、releases.exs
の設定が優先されることがわかります。
環境変数を指定して実行します。
$ FOO=hoge BAR=fuga _build/dev/rel/hoge/bin/hoge start foo: {:ok, "foo"} bar: {:ok, "fuga"}
config/release.exs
で設定していない foo
はビルド時の環境変数の値になっています。
一方 config/releases.exs
で設定した bar
は慈光寺の環境変数の値になっています。
releases.exs の在り処
最後に。 releases.exs
がどこで利用されているか確認します。
$ find . -name releases.exs ./config/releases.exs ./_build/dev/rel/hoge/releases/0.1.0/releases.exs
config/releases.exs
はリリース版に同梱されていることがわかります。
またアプリケーションを起動するスクリプト _build/dev/rel/hoge/bin/hoge
を読んでみると、_build/dev/rel/hoge/releases/0.1.0/sys.config
のコピーを読み込んでいることがわかります。
このファイルの内容を確認すると次のようになっています。 実際のファイルではコメント行以外は一行で記述されていますが、ここでは読みやすいように改行とインデント、およびバイナリ部分にコメントを追加しました。
Erlang の内容に踏み込んでしまうので深追いはしませんが、同梱された releases.exs
を Config.Reader
で利用するように設定されていることがわかります。
%% coding: utf-8 %% RUNTIME_CONFIG=true [ { hoge, [ {foo, nil}, {bar, nil} ] }, { elixir, [ { config_providers, #{ '__struct__' => 'Elixir.Config.Provider', config_path => { system, % "RELEASE_SYS_CONFIG" <<82,69,76,69,65,83,69,95,83,89,83,95,67,79,78,70,73,71>>, % ".config" <<46,99,111,110,102,105,103>> }, extra_config => [ { kernel, [ {start_distribution, true} ] } ], providers => [ { 'Elixir.Config.Reader', { system, % "RELEASE_ROOT" <<82,69,76,69,65,83,69,95,82,79,79,84>>, % "/releases/0.1.0/releases.exs" <<47,114,101,108,101,97,115,101,115,47,48,46,49,46,48,47,114,101,108,101,97,115,101,115,46,101,120,115>> } } ], prune_after_boot => false } } ] }, { kernel, [ {start_distribution, false} ] } ].
いつか読むはずっと読まない:mismatch
昨年まで 3 年近く関わったプロジェクトではバックエンドの部分を担ったため、エンドユーザはあまり意識せずに開発をしていました。
今年から再びフロントエンドを含むウェブサービスの開発に参加することになりましたが、一番に戸惑ったのがフロントエンドの書き方、特にテストの書き方を結構忘れてしまっていたこと。 幸いすぐに勘を取り戻すことができましたが、そういったものに気を取られることがなくなるとアプリケーションが提供している操作そのものに意識が向くようになります。
ミスマッチ 見えないユーザーを排除しない「インクルーシブ」なデザインへ
- 作者: キャット・ホームズ,ジョン・マエダ,大野千鶴
- 出版社/メーカー: ビー・エヌ・エヌ新社
- 発売日: 2019/03/15
- メディア: 単行本
- この商品を含むブログを見る