読者です 読者をやめる 読者になる 読者になる

Lambdaカクテル

ソフトウェア開発者です.玉石混淆です.

play distで作成したartifactにtypesafe-configを注入する

play akka scala

ども。今回はPlay Framework 2.2.xのdistコマンドで生成される成果物の扱いに関してのお話です。

まとめると
  • distすると後からconf/以下のファイルを編集しても意味無し
  • -Dconfig.file=で指定すると読んでくれる
  • 二つ以上の.confを読ませるとハマることがある
本文

$play distではプログラムを成果物として固めることができますが、その際conf/ディレクトリ以下の設定ファイルも一緒に固められます。何もせずとも、dist時の設定が再現されます。

さて、後からデプロイ先の環境に合わせて設定を変更しなければならない場合があります。playが利用するデータベースの名前であったり、自分が組み込んだライブラリの設定だったりです。私の場合ではPlayの各種設定とAkkaの設定でした。これらは両者ともにTypesafe-configを利用しているため、同じように扱うことができます。

distで生成されたZIPファイルにもconf/ディレクトリが存在しますが、この中身を弄ってもアプリケーションは設定を読みません(なぜそうなるのかは私でもよくわからない)。固めた後に設定を読ませるには、起動スクリプトに引数を渡す必要があります。

$ unzip myApplication-0.0.0
$ cd myApplication-0.0.0/
[myApplication-0.0.0] $ emacs conf/application.conf
[myApplication-0.0.0] $ chmod u+x bin/myApplication
[myApplication-0.0.0] $ bin/myApplication -Dconfig.file=conf/application.conf

最終行に注目してください。-Dconfig.fileを利用して設定ファイルを指定しています。これによりtypesafe-configが既存の設定ソースをオーバーライドし、指定した設定ファイルを読むようになります。

ただし、以下の場合は正しく動作しません。

  • 複数の設定ファイルを指定したとき

具体的に示すと以下のような場合です。

[myApplication-0.0.0] $ bin/myApplication -Dconfig.file=hoge.conf -Dconfig.file=fuga.conf

このような場合では、config.fileシステムプロパティが二度上書きされることになるため、最後に指定された-Dconfig.file=fuga.confのみが有効となり、-Dconfig.file=hoge.confは結果的に無視されます。私もここでハマりました。

typesafe-config設定ファイルが複数にならざるを得ない場合は、distで生成された成果物中のconf/ディレクトリの.confファイルをマージして一つのファイルとして提供し、起動スクリプトで指定してやる必要があります。

[myApplication-0.0.0] $ merge -p conf/*.conf > conf/merged.conf
[myApplication-0.0.0] $ bin/myApplication -Dconfig.file=conf/merged.conf

この方法はtypesafe-configを利用するライブラリやアプリケーションにのみ有効であり、その他のコンフィグローダを利用するアプリケーションについては無効です。

この方法はPlay frameworkのapplication.confと、その他のtypesafe-configを利用するライブラリが使う設定ファイル(reference.conf)が両方存在する場合に有効です。

application.confと他の.confファイルは最初からマージしてもいいんじゃないかと思いますが、reference.confという名前でないといけない場合があるのでこの手段を採らざるをえない場合があります。Akkaを利用するライブラリをアプリケーションに導入する場合、conf/reference.confを読まなければならないとされている(らしい?)ためです。

おわり

Playは詳しい解説が少ない気がする。