なんとな~くしあわせ?の日記

「そしてそれゆえ、知識そのものが力である」 (Nam et ipsa scientia potestas est.) 〜 フランシス・ベーコン

mavenで本番用/開発用のwarファイル切り替え

f:id:panzer-jagdironscrap1:20171018130045p:plain

成果物の設定情報切り替え

ユースケース

システム開発を行う際、DBやサーバを本番環境、開発環境(あるいは+ステージング環境)に用意することは当たり前のことだろう。

上記のようにすることで

  • 開発環境で事前にテストすることでバグが発見しやすくなる
  • 本番環境のデプロイのノウハウがたまってミスりにくくなる

ここからさらに進めて自動デプロイ環境、いわゆるCIを用意していくのが最近の潮流です。というかそうしないで人の手でやるのは時間がかかるしミスが多い。

実際に使われる環境変数

接続先データベースのURLや秘密のトークン文字列などを環境ごとに分けます。これにより、同じアプリケーションを起動するときに、環境変数を切り替えれば本番用/開発用の環境が切り替えられます。

他のフレームワークでの方法

Rubyには dotenv というフレームワークがあり、最初から環境は3種類用意することが前提になっています。development, staging, productionそしてtest。ごめんなさい4種類でした。

testに関してはユニットテストで実行される際の環境変数を提供するという認識です。

GitHub - bkeepers/dotenv: A Ruby gem to load environment variables from `.env`.

mavenで本番用/開発用のwarファイル切り替え

profile

mavenにはビルドの際にオプションとして「-P env」という形式で切り替え用の環境を与えられます。

maven resources plugin

profileごとに使用するプロパティファイルを切り替えるとき Maven Resources Plugin が使えます。

環境ごとの切り替えの実装

プロパティファイルの値の置き換え

  • resource タグで指定された場所にあるファイルが、変数の置き換え対象になります
<project>
  ...
  <name>jdbc:postgresql://localhost/test</name>
  ...
  <build>
    ...
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
      </resource>
      ...
    </resources>
    ...
  </build>
  ...
</project>
  • src/main/resources/config.properties
jdbc.url=${name}

こういう風に設定しておくと、mavenでのビルド後にプロパティファイルの中身が書き換わります。

jdbc.url=jdbc:postgresql://localhost/test

書き換わったファイルが入るのは、ビルド後にクラスファイルが入る target/classes 以下になります。

プロパティの置き換えを「-P env」オプションで行う

以下のサイトの内容の受け売りになりますが

pom.xmlの中身を以下のように設定すると

  • 「mvn -P dev compile」
  • 「mvn -P prod compile」
  • 「mvn -P test compile」

で切り替えられるようになります。

<!-- プロファイル設定 -->
<profiles>
    <profile>
        <id>dev</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <build.profile.id>dev</build.profile.id>
        </properties>
    </profile>
    <profile>
        <id>prod</id>
        <properties>
            <build.profile.id>prod</build.profile.id>
        </properties>
    </profile>
    <profile>
        <id>test</id>
        <properties>
            <build.profile.id>test</build.profile.id>
        </properties>
    </profile>
</profiles>

<!-- プロパティ値の取得元(dev/prod/testというディレクトリ)を用意しておく -->
<filters>
    <filter>profiles/${build.profile.id}/config.properties</filter>
</filters>

<!-- プロパティ値の適用先ファイル -->
<resources>
    <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
    </resource>
</resources>