relx コトハジメ の内容を把握している読者を想定しています。
Dockerイメージなどを開発環境にしていると、なるべく実際に動く環境に近いような動作環境でテストしたくなります。
一方で、開発環境というのはなるべく手間なく勝手にコンパイルやテストが走ったり、変更点を勝手にリロードしてほしいものです。
relx を使ってリリースイメージに近いような環境でソフトウェアを起動しつつ、 sync を使って自動コンパイル&リロードする環境を作ろうというのがこの記事の趣旨です。
$ mkdir myapp
$ cd myapp
$ cp /path/to/rebar .
$ cp /path/to/relx .
$ ./rebar create-app appid=myapp
==> myapp (create-app)
Writing src/myapp.app.src
Writing src/myapp_app.erl
Writing src/myapp_sup.erl
普通です。 rebar のテンプレートでアプリのひな形を作ります。
dev_relx.config
{release, {myapp, "0.0.1"},
[sasl, myapp]}.
{extended_start_script, true}.
{output_dir, "dev"}.
$ ./rebar get-deps compile
==> myapp (get-deps)
==> myapp (compile)
Compiled src/myapp_app.erl
Compiled src/myapp_sup.erl
$ ./relx -c dev_relx.config
===> Starting relx build process ...
===> Resolving OTP Applications from directories:
/home/y-sudo/project/0206/myapp/ebin
/home/y-sudo/kerl/R16B03-1/lib
===> Resolved myapp-0.0.1
===> Including Erts from /home/y-sudo/kerl/R16B03-1
===> release successfully created!
私はこういうのは Makefile にしちゃうのが好みです。
$ ./dev/myapp/bin/myapp console
(中略)
(myapp@127.0.0.1)1>
無事起動しました。ここまでは voluntas さんの記事の通りです。
(myapp@127.0.0.1)1> q().
終了しときます。
sync という Erlangアプリがあり、ファイルシステムを監視して、ソースコードが変更されたら自動コンパイル&リロードしてくれる素敵なアプリです。
ただ、sync は開発用途のソフトウェアで sync:go()
してやらないと監視を開始してくれません。それはそれでもっともだと思いますが、 開発用Dockerイメージなどではイメージ起動したら勝手にソースの更新チェックとかしてほしいです。結局 console 開くことにはなるけど、毎度 sync:go()
叩くのも面倒です。
そこで sync:go()
するだけの auto_syncer というアプリケーションを作ったので、こいつを使ってやります。
rebar.config
{deps, [
{auto_syncer, ".*", {git, "https://github.com/ajiyoshi/auto_syncer.git"}}
]}.
rebar.config
のdepsに追加
dev_relx.config
{release, {myapp, "0.0.1"},
[sasl, myapp, auto_syncer]}.
{extended_start_script, true}.
{output_dir, "dev"}.
auto_syncer
をリリースに含めてやります
$ ./rebar get-deps
==> myapp (get-deps)
Pulling auto_syncer from {git,"https://github.com/ajiyoshi/auto_syncer.git"}
Cloning into 'auto_syncer'...
==> auto_syncer (get-deps)
Pulling sync from {git,"https://github.com/rustyio/sync.git"}
Cloning into 'sync'...
==> sync (get-deps)
$ ./rebar compile
==> sync (compile)
Compiled src/sync.erl
Compiled src/sync_notify.erl
Compiled src/sync_scanner.erl
Compiled src/sync_options.erl
Compiled src/sync_utils.erl
==> auto_syncer (compile)
Compiled src/auto_syncer_app.erl
Compiled src/auto_syncer_sup.erl
==> myapp (compile)
$ ./relx -c dev_relx.config
===> Starting relx build process ...
===> Resolving OTP Applications from directories:
/home/y-sudo/project/0206/myapp/ebin
/home/y-sudo/project/0206/myapp/deps
/home/y-sudo/kerl/R16B03-1/lib
===> Resolved myapp-0.0.1
===> Including Erts from /home/y-sudo/kerl/R16B03-1
===> release successfully created!
これで、アプリケーションを起動するだけでソースコードを自動コンパイル&リロードしてくれるリリースビルドができました。起動してみます。
$ ./dev/myapp/bin/myapp console
(中略)
(myapp@127.0.0.1)1>
ソースコードを適当に変更したら、自動リロードされます
src/myapp_app.src
を適当に編集。
-module(myapp_app).
-behaviour(application).
%% Application callbacks
-export([start/2, stop/1]).
-export([hello/0]).
%% ===================================================================
%% Application callbacks
%% ===================================================================
start(_StartType, _StartArgs) ->
myapp_sup:start_link().
stop(_State) ->
ok.
hello() ->
hello.
(myapp@127.0.0.1)1>
=INFO REPORT==== 8-Feb-2015::14:24:41 ===
/home/y-sudo/project/0206/myapp/src/myapp_app.erl:0: Recompiled.
=INFO REPORT==== 8-Feb-2015::14:24:41 ===
myapp_app: Reloaded! (Beam changed.)
(myapp@127.0.0.1)2> myapp_app:hello().
hello
便利。