HelidonベースのアプリケーションをAzure App Serviceにデプロイする

このエントリは2020/06/29現在の情報に基づいています。将来の機能追加や変更に伴い、記載内容との乖離が発生する可能性があります。

HelidonはOracleがオープンソースとして公開している、QuarkusやMicronautなどと類似のWebアプリケーション開発フレームワーク。Helidonの詳細は以下を参照。

Project Helidon
https://helidon.io

現在1.4.4、ならびに2.0.0がリリースされている。このエントリでは、Helidonで作成したアプリケーションをAzure App Serviceにデプロイする手順を紹介する。以下の点だけ注意すれば難しくない。

  • 依存関係の追加
  • 適切なJDKの利用
    • 1.4.4ではJava 8以後のJDKを利用
    • 2.0以後ではJava 11以後のJDKを利用
  • App Service用の構成
    • デプロイ対象のJarファイルの指定

今回はQuickStartアプリケーションを作成することにする(もちろんMicroProfile Starterを使ってもOK)。利用するHelidonのバージョンは2.0.0。

事前に準備しておくもの

デプロイに至るまでに以下が必要。

  • JDK
    • Helidon 1.xの場合、JDK 8以上
    • Helidon 2.xの場合、JDK 11以上
  • Maven
  • Azure CLI (Maven Plugin for Azure App ServiceからAzure CLIを呼び出しているため)

Helidon側での構成

ソースコードの生成

Mavenでソースコードを作成する。

Helidon SE Quickstart
https://helidon.io/docs/v2/#/se/guides/02_quickstart

mvn archetype:generate -DinteractiveMode=false \
    -DarchetypeGroupId=io.helidon.archetypes \
    -DarchetypeArtifactId=helidon-quickstart-se \
    -DarchetypeVersion=2.0.0 \
    -DgroupId=io.helidon.examples \
    -DartifactId=helidon-quickstart-se \
    -Dpackage=io.helidon.examples.quickstart.se

Helidon MP Quickstart
https://helidon.io/docs/v2/#/mp/guides/02_quickstart

mvn archetype:generate -DinteractiveMode=false \
    -DarchetypeGroupId=io.helidon.archetypes \
    -DarchetypeArtifactId=helidon-quickstart-mp \
    -DarchetypeVersion=2.0.0 \
    -DgroupId=io.helidon.examples \
    -DartifactId=helidon-quickstart-mp \
    -Dpackage=io.helidon.examples.quickstart.mp

helidon-quickstart-seもしくはhelidon-quickstart-mpというディレクトリに諸々作成されていることを確認する。

依存関係の追加

App Service用のプラグイン(Maven Plugin for Azure App Service)を追加する。

<plugin>
 <groupId>com.microsoft.azure</groupId>
 <artifactId>azure-webapp-maven-plugin</artifactId>
 <version>1.9.1</version>
</plugin>

このあたりはSpring Bootの場合と同じ。

Azure App Service 用の Maven プラグインを構成する / Configure Maven Plugin for Azure App Service
https://docs.microsoft.com/azure/developer/java/spring-framework/deploy-spring-boot-java-app-with-maven-plugin#configure-maven-plugin-for-azure-app-service

Azure App Service用の構成

以下のコマンドを実行し、App Serviceの構成を設定する。

mvn azure-webapp:config

よく見るMavenの出力のあと、OS、Javaのバージョンを指定する入力が現れるので、使いたい設定を指定する。以下は入力例。

[WARNING] The plugin may not work if you change the os of an existing webapp.
Define value for OS(Default: Linux):
1. linux [*]
2. windows
3. docker
Enter index to use: 1
Define value for javaVersion(Default: Java 8):
1. Java 11
2. Java 8 [*]
Enter index to use: 1
Please confirm webapp properties
AppName : helidon-quickstart-se-1591346807867
ResourceGroup : helidon-quickstart-se-1591346807867-rg
Region : westeurope
PricingTier : PremiumV2_P1v2
OS : Linux
RuntimeStack : JAVA 11-java11
Deploy to slot : false
Confirm (Y/N)? : Y
[INFO] Saving configuration to pom.
...

なお、リージョンやリソースグループ、App Serviceの名前、Pricing Tierなどはこのタイミングでは指定できないので、pom.xmlを直接編集する必要がある。以下は、上記実行後のpom.xmlの例。

... 
     <plugin> 
        <groupId>com.microsoft.azure</groupId>  
        <artifactId>azure-webapp-maven-plugin</artifactId>  
        <version>1.9.1</version>  
        <configuration>
          <schemaVersion>V2</schemaVersion>
          <resourceGroup>helidon-quickstart-se-1591346807867-rg</resourceGroup>
          <appName>helidon-quickstart-se-1591346807867</appName>
          <pricingTier>P1v2</pricingTier>
          <region>westeurope</region>
          <runtime>
            <os>linux</os>
            <javaVersion>java11</javaVersion>
            <webContainer>java11</webContainer>
          </runtime>
          <deployment>
            <resources>
              <resource>
                <directory>${project.basedir}/target</directory>
                <includes>
                  <include>*.jar</include>
                </includes>
              </resource>
            </resources>
          </deployment>
        </configuration>
      </plugin>  
...

デプロイ対象の指定

ビルドすると以下のコンテンツが出力される。

  • targetディレクトリ:依存関係を含まないJAR
  • target/libsディレクトリ:依存関係にあたるJAR

デフォルトのpom.xmlの記述でデプロイすると、 ${project.basedir}/target に存在する *.jar にヒットするJARファイル、つまり依存関係を含まないJARファイル(この場合、helidon-quickstart-se.jarもしくはhelidon-quickstart-mp.jar)だけがapp.jarとしてデプロイされてしまい、依存関係がないために正常に動作しない。これを避けるため、 以下のいずれかの設定を追加する。

  1. デプロイ対象として、**/*.jarを指定する。これにより、${project.basedir}/target以下、サブディレクトリを含むJarファイルをデプロイ対象にできる。
<deployment>
  <resources>
    <resource>
      <directory>${project.basedir}/target</directory>
      <includes>
         <include>**/*.jar</include>
      </includes>
    </resource>
  </resources>
</deployment>
  1. <include>タグで明示的に /libs/*.jar を追加する。これは ${project.basedir}/target だけでなく、 ${project.basedir}/target/libs/ 内のJarファイルも明示的にデプロイ対象にしている。
<deployment>
  <resources>
    <resource>
      <directory>${project.basedir}/target</directory>
      <includes>
         <include>*.jar</include>
         <include>/libs/*.jar</include>
      </includes>
    </resource>
  </resources>
</deployment>

もちろん、maven assembly pluginを使って依存関係も含んだJARファイルを作成することでも対応できるが、Helidon MPではmainメソッド無しでの起動が可能なため、Executable Jarを作成するよりも考慮事項が少なくて済む、という利点がある。

Technically, the main class is not needed unless you want to control the startup sequence. You can set the mainClass to io.helidon.microprofile.Main and it will find the application annotated with ApplicationScoped. Though it is likely that almost any “real” application would want its own main class.

Start implementing the MicroProfile application – Helidon MP Tutorial
https://helidon.io/docs/v2/#/mp/guides/10_mp-tutorial

リスニングポート

以下のドキュメントには、App Serviceは80/tcpで着信する、との記述がある。

App Service Linux では着信要求がポート 80 にルーティングされるため、アプリケーションもポート 80 でリッスンする必要があります。 これはアプリケーションの構成 (Spring の application.properties ファイルなど)、またはスタートアップ コマンド (たとえば、java -jar spring-app.jar --server.port=80) で行うことができます。

サーバー ポート / Server Port
https://docs.microsoft.com/azure/app-service/containers/configure-language-java#server-port

Helidonの場合、MP、SEともにデフォルトのリスニングポートは8080/tcpである。そのため、App Serviceの仕様に合わせて変更しておく、もしくはポートバインディング、の2通りの方法がある(DockerコンテナをApp Serviceにデプロイする場合は、ポートバインディングを使う)。

ポートバインディング

pom.xmlの<configuration>タグ内に<appSettings>を追加してWEBSITES_PORTをコンテナ側のポート、PORTを公開側のポートとして指定する。以下はその例。

<configuration>
    ...
          <appSettings>
            <property>
              <name>PORT</name>
              <value>8080</value>
            </property>
            <property>
              <name>WEBSITES_PORT</name>
              <value>8080</value>
            </property>
          </appSettings>
      ...
     </configuration>

ポートの変更(SEの場合)

resources/application.yamlがあり、この中のserver.portがリスニングポート。デフォルトでは8080が定義されているので、これを変更して80にしておく。

app:
  greeting: "Hello"

server:
  port: 80
  host: 0.0.0.0

ポートの変更(MPの場合)

META-INF/microprofile-config.propertiesのserver.portがリスニングポート。デフォルトでは8080が定義されているので、これを変更して80にしておく。

# Application properties. This is the default greeting
app.greeting=Hello

# Microprofile server properties
server.port=80
server.host=0.0.0.0

ビルドとデプロイ

80/tcpをリスニングポートに設定している場合、一般ユーザーによるテスト実行では特権ポートを使うサービス開始にあたってエラーが出る点には注意が必要。

mvn package

App Serviceへのデプロイはmvn azure-webapp:deployを使う。デプロイはAzureへの認証が済んでいることが前提なので、Azure CLIなどで認証を済ませておくこと。

# Azure CLIで認証
az login

# サブスクリプションが複数ある場合は、デプロイ対象のサブスクリプションを指定しておいたほうがいい
az account set -s "サブスクリプションIDもしくはサブスクリプション名"

# デプロイ! 
mvn azure-webapp:deploy

Azure側の構成

FTPやFTPSでのデプロイを許可しないのであれば、Azure PortalでSettings (設定) > Configuration (構成) > General settings (全般設定) のFTP state (FTP の状態) をDisabled (無効) にしておく。設定が完了したら、Save (保存) しておく。

SSHでApp Serviceのコンテナ内に入って確認(省略可)

これは実際にデプロイされている内容を確認しているだけなので、常に実行する必要はない。Azure Portalから、Development Tools (開発ツール) > SSH でApp ServiceのコンテナにTerminalでアクセスできる。デプロイしたJarファイルがどのように格納されているかを確認してみる。

/home/site/wwwrootがアプリケーションデプロイ先なので、ここへ移動すると、以下のスクリーンショットのように、helidon-quickstart-se.jarもしくはhelidon-quickstart-mp.jarがapp.jarとして存在し、libsディレクトリ内に依存関係のJarファイルが入っていることがわかる。

動作確認

Quickstartアプリケーションはhttps://<App Service URL>/greet/Taro1でHello Taro1!を返すはずなので、実際にやってみると…。

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Google フォト

Google アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中