LastaFluteのデプロイ環境

LastaFluteにおけるビルドデプロイのやり方です。マルチプロジェクトを想定しています。 シングルプロジェクトでは、一つになって単純になるだけですので、ぜひ空気を読んでください。

実行可能warでアプリ起動

warをjavaコマンドで実行

組み込みJetty, 組み込みTomcatを使って、warファイルをjavaコマンドで実行することでアプリを起動させるのが基本です。 (必須ではないですが、その方式で問題なければという感じで)

e.g. javaコマンドでwarファイルを実行、組み込みJetty,Tomcatが起動する @Command
java -jar maihama-dockside.war

lasta.envを指定

実際には、結合環境、本番環境と設定を切り替える必要があるかと思います。 環境設定を切り替えるためには、javaコマンドでシステムプロパティ lasta.env を指定します。

e.g. javaコマンドで lasta.env に production (本番) を指定 @Command
java -Dlasta.env=production -jar maihama-dockside.war

これにより、アプリで読み込まれる ..._env.properties が切り替わります。

例えば、lasta.env が production であれば、..._env_production.properties が読み込まれます。 (普段のローカル開発環境では lasta.env は指定されないので、ローカル用の ..._env.properties が読み込まれます)

ポート番号をスイッチ

デプロイ環境ではポート番号を別にしたいなら、lasta.env の有無で分岐するとよいでしょう。

e.g. デプロイ環境ではport番号を 8080 にする (結合も本番も同じだとして) @Java
private static final int DEVELOPMENT_PORT = 8091;
private static final int PRODUCTION_PORT = 8080;

public static void main(String[] args) { // e.g. java -Dlasta.env=production -jar maihama-dockside.war
    new TomcatBoot(derivePort(), "/dockside").asDevelopment(isNoneEnv()).bootAwait();
}

private static int derivePort() {
    return isNoneEnv() ? DEVELOPMENT_PORT : PRODUCTION_PORT;
}

private static boolean isNoneEnv() {
    return System.getProperty("lasta.env") == null;
}

もっと、細かくデプロイ環境ごとに変更したいとかであれば、javaコマンドの引数で指定したりしてもよいでしょう。 main() の args から指定された port 番号を取得できるようにするなど。

インストールTomcatで起動

こちらでも lasta.env を忘れずに

組み込みTomcat (jar起動) ではなく、インストールしたTomcat にwarを配備させて動作させる場合は、必ず Tomcat 側のJava実行時のプロパティ指定で lasta.env を設定してください。

jar起動でもwar配備でも、Javaプロパティの lasta.env で [app]_env.properties を切り替えることには変わりません。 lasta.env を設定しないで配備して起動した場合は、ローカル開発環境用の設定で動いてしまいます。(例えば、HotDeployのままで起動してしまいます)

実行可能warをそのまま配備できる

実行可能warは、インストールTomcat (シェルなどで実行するTomcat) などに配備できる形をキープしています。 なので、実行可能でもあるし、そのままインストールTomcatに配備することもできます。 (実行可能warの中身に関しては後述)

この場合、[App]Bootクラスは利用されずに起動することになります。

Mavenでwarファイル作成

継承や依存などの Maven の構成を把握していることを前提として...(LastaEnvを前提に)

実行可能warの作り方

[service]-base にて mvn -e clean package を叩けばOKです。 (aggregateしているため)

できあがったwarファイルは環境依存をしていません ので、javaコマンド実行時にシステムプロパティとして lasta.env を指定しましょう。(LastaEnv方式)

e.g. 本番環境(production)としてアプリを実行 @Command
java -Dlasta.env=production -jar maihama-dockside.war

すると、参照される [app]_env.properties が切り替わります。

(ちなみに、Maven-3.1.1 より古いバージョンだとうまくwarファイルが作成されないという報告がありますので、 そのときは Maven のアップグレードをお願いします)

実行可能warの中身

Jetty/Tomcat起動の世界 と、アプリの世界 が一つにまとまっています。

war直下 (WEB-INF除く)
Jetty/Tomcat起動の世界 (Bootクラスのためのクラスやリソースたち)
WEB-INF配下
アプリの世界 (アプリのためのクラスやリソースたち)

(一度、warを作ってみて解凍して中身を見てみると理解が深まるでしょう)

Jetty/Tomcat起動の世界から、アプリの世界のクラスやリソースは参照できないので、[App]Bootクラスで利用できるクラスやリソースは限られています。 [App]Bootクラスで、[app]_env.propertiesなどを参照する場合は、それらをwar直下に配置する必要があります。(後述)

実行可能warの設定

pom.xml では、このような定義がされています。

Jettyなら
plugins in pom.xml for Jetty (harbor) | Github
Tomcatなら
plugins in pom.xml for Tomcat (dockside) | Github

(行番号へのリンクなので、位置が変わってる可能性があります: plugin定義の maven-dependency-plugin と maven-war-plugin のところを探しましょう)

実行可能warに含めるリソース

先ほどの記述の通り、[App]Bootクラスで [app]_env.propertiesなどを参照する場合は、war直下にそれらリソースを配置する必要があります。 maven-war-plugin にてそれらリソースをincludeします。(先述の通り、Jetty/Tomcat起動の世界から、アプリの世界のクラスやリソースは参照できないので)

e.g. Bootクラスで、propertiesなどのリソースを使えるように for Tomcat @pom.xml
    ...
    <webResources>
        <resource>
            ...
            <includes>
                <include>**/*Boot*.class</include>
                <!-- properties may be used by the boot class -->
                <include>*_config.properties</include>
                <include>*_env*.properties</include>
                <include>tomcat_*.properties</include>
            </includes>
        </resource>
    </webResources>

マルチプロジェクトの場合、これだけだと "commonプロジェクト" の properties が含まれません。 これに関しては、現時点でスマートな解決方法がないため、ベタベタに書いてコピーします。(何か良い方法があれば教えてください...)

e.g. commonプロジェクト、propertiesなどのリソースを使えるように for Tomcat @pom.xml
    ...
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-resources-plugin</artifactId>
        <executions>
            <execution>
                <id>copy-common-resources</id>
                <phase>generate-resources</phase>
                <goals>
                    <goal>copy-resources</goal>
                </goals>
                <configuration>
                    <outputDirectory>${basedir}/target/${project.build.finalName}</outputDirectory>
                    <overwrite>true</overwrite>
                    <resources>
                        <resource>
                            <directory>${basedir}/../maihama-common/src/main/resources</directory>
                            <includes>
                                <include>*_config.properties</include>
                                <include>*_env*.properties</include>
                                <include>tomcat_*.properties</include>
                            </includes>
                        </resource>
                    </resources>
                </configuration>
            </execution>
        </executions>
    </plugin>

新しいデプロイ環境をつくる

新しいデプロイ環境 (profile) をつくる場合は、いくつかの設定ファイルを修正していく必要があります。

まずは、Mavenの構成、および、環境切り替えの構成を把握していることを前提として...

例えば、sea という名前の環境を新たに作るとします。

1. resources に環境依存propertiesを追加

src/main/resources に xxx_env_sea.properties を追加します。別の環境の xxx_env.properties をコピーして作るとよいです。 が、修正漏れだけには厳重注意しましょう。

プロパティ値だけでなく、コメントの中も新しい環境に合わせましょう。(環境名とか書いてあるかも)

2. ReplaceSchemaの環境設定を追加 (必要であれば)

これは、新しい環境のDBを ReplaceSchema 管理するときだけの話です。

dfpropの環境切り替えの構成について把握していることを前提として...

  1. DBFluteクライアント/dfprop/sea フォルダを作成
  2. そこに、databaseInfoMap+.dfprop と replaceSchemaMap+.dfprop を作成
  3. databaseInfoMap+.dfprop の設定
  4. replaceSchemaMap+.dfprop の設定
  5. DBFluteクライアント/__sea_manage.sh を作成 (環境変数をseaに)

__sea_manage.sh を叩けば、sea環境用の設定で ReplaceSchema できるようになります。

新しいWebプロジェクトつくる

TODO jflute