Posted at

Spring BootでWARに含めるapplication.propertiesを環境ごとにビルド時に切り替える

More than 3 years have passed since last update.

Spring BootでWARを作成して別のTomcatにデプロイするでも書いた通り、開発中はSpring Bootの組み込みTomcatを使って開発するが、テスト環境や本番環境では予め用意されている別のTomcatにWARをデプロイして動作させる、なんてケースがあると思います。その時のapplication.propertiesってどうしていますか?という話です。

例えば、dev1~dev3という環境があるとします。dev1にはdev1の設定(DBの接続先やスキーマ等)を持っているapplication.propertiesを、dev2にはdev2の設定を持っているapplication.propertiesを、dev3にはdev3の設定を持っているapplication.propertiesをビルド時にWARに含めちゃえばいいと思いませんか?


Spring Bootのprofile機能では実現できない

一般的にSpring Bootのapplication.properties周りの構成は以下のような感じになっています。

1.png

試しにこの状態で以下2つのやり方で試してみます。


Spring Boot起動時のprofile機能を利用してみる

Spring Bootでは以下のようにすることで動的にprofileを切り替える仕組みがあります。公式ではちょうどこの部分で語られています。

java -jar -Dspring.profiles.active=dev1 spring-boot-application-properties-1.0.0.jar

ただし、これはあくまでSpring Bootの組み込みTomcatを使ったTomcat起動時の話です。成果物であるjarをjavaコマンドで実行する、という前提があります。この場合、環境ごとに以下のようなコマンドを予め用意しておくだけで事足ります。

dev1という環境で動作させる場合

java -jar -Dspring.profiles.active=dev1 spring-boot-application-properties-1.0.0.jar

dev2という環境で動作させる場合

java -jar -Dspring.profiles.active=dev2 spring-boot-application-properties-1.0.0.jar

dev3という環境で動作させる場合

java -jar -Dspring.profiles.active=dev3 spring-boot-application-properties-1.0.0.jar

タイトルにもある通り「WARに含めるapplication.propertiesを環境ごとにビルド時に切り替える」とは別の話なので、上記では実現できません。


application.propertiesのspring.profiles.active=XXXを利用してみる


application.properties

spring.profiles.active=dev1


これであれば切り替えは出来そうです。

ただし、「WARに含めるapplication.propertiesを環境ごとにビルド時に切り替える」という点では、動的にactiveを切り替えることができないため、デプロイしたい環境が変わる度にapplication.propertiesのspring.profiles.active=のところを修正してコミットしてビルドしなおす必要あります(dev2という環境にデプロイしたい場合、spring.profiles.active=dev2に修正してコミットが必要、dev3でも同じことが言える)。


どうするか?

こんな時はMavenのprofile機能を使って解決します。

以下のように、「src/環境識別子/resources」の構成でディレクトを作成し、それぞれの環境の設定を記載したapplication.propertiesを配置します。

2.png

ここでは便宜的に以下のようにしました。


src/dev1/resources/application.properties

# dev1 environment setting



src/dev2/resources/application.properties

# dev2 environment setting



src/dev3/resources/application.properties

# dev3 environment setting


次に、以下のようにpom.xmlにprofileを記載します。


pom.xml

<profiles>

<profile>
<id>dev1</id> // ←環境識別子
<build>
<resources>
<resource>
<directory>src/dev1/resources</directory>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
</profile>
<profile>
<id>dev2</id> // ←環境識別子
<build>
<resources>
<resource>
<directory>src/dev2/resources</directory>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
</profile>
<profile>
<id>dev3</id> // ←環境識別子
<build>
<resources>
<resource>
<directory>src/dev3/resources</directory>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
</profile>
</profiles>

※mavenのprofileについてはMaven3で環境ごとのresourceを差分で管理する方法を参考にしてもらえたらと思います。

最後に、以下のように-Pオプションに環境識別子(pom.xmlのid属性に指定した値、ここではdev1とかdev2とかdev3がそれにあたる)を指定してビルドします(WARファイルを作成します)。


ビルドしてwarファイルを作成する.

mvn package -Pdev1 spring-boot:repackage


出来たWARを確認してみると、application.propertiesが1つだけになっていることが分かります。また、中身を確認すると-Pオプションで指定した環境識別子(ここではdev1)のresources配下のapplication.propertiesがWARに含まれていることもわかります。

dev2にデプロイしたい場合は、以下のようにするだけです。


dev2へデプロイのためのビルド.

mvn package -Pdev2 spring-boot:repackage


こうすることで、今度はsrc/dev2/resources/application.propertiesがWARに含まれます。


結論

Spring Bootの話かと思いきやMavenの話っぽくなってしまいましたが、Mavenのprofile機能を使えば可能です。