Deploying Helidon applications to Azure App Service
[As of June 29, 2020]
Japanese edition is here.
Similar to the following article, I will describe how to deploy Helidon applications to Azure App Service.
Deploying Helidon Applications to Google App Engine
What is Helidon?
Helidon is an open-sourced web application development framework developed by Oracle. This is similar to Quarkus and Micronaut.
At the time of writing this article, the latest version is 1.4.4 and 2.0.0.
In this article, I use the quickstart application of Helidon 2.0.0 SE/MP for demonstration. For more details on the quickstart application of each edition, please check the following URLs.
We can use hello world app created via MicroProfile Starter, of course.
Deployment key points
Key points are listed below.
- Adding dependencies and proper settings for Azure App Service
- Using proper JDK suitable for Helidon version
Prerequisites
The following items are required to complete building and deploying applications.
- JDK (JDK 8 or higher for Helidon 1.x, JDK 11 or higher for Helidon 2.x)
- Maven
- Azure CLI (needed to call Azure CLI from Maven Plugin for Azure App Service)
Generating resources
Use Maven to generate Quickstart application resources.
# Helidon SE
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
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
Please confirm resource files are generated in either {current directory}/helidon-quickstart-se or {current directory}/helidon-quickstart-mp directory, depending upon calling command.
Adding dependencies
Add “Maven Plugin for Azure App Service” to pom.xml.
<plugin>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-webapp-maven-plugin</artifactId>
<version>1.9.1</version>
</plugin>
This operation is similar to that for Spring Boot application.
Configure Maven Plugin for Azure App Service
Configuration for Azure App Service
Invoke the following command to add configuration for Azure App Service.
mvn azure-webapp:config
Specify the operating system and the Java version as follows. If you want to change either the region to be deployed, resource group, name of App Service or Pricing Tier, you have to finish this command and modify settings in pom.xml directly.
[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.
...
The following output is an excerpt from pom.xml modified in executing the command.
...
<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>
...
Specifying deployment targets
When building an application, the following artifacts are generated and stored in each directory.
- JAR file without dependencies: ${project.basedir}/target
- Dependency JAR files: ${project.basedir}/target/libs
If using default pom.xml to deploy to Azure App Service, only JAR file without dependencies is deployed. In this case, either helidon-quickstart-se.jar or helidon-quickstart-mp.jar is renamed to app.jar and app.jar only is deployed to Azure. So, this application does not work properly due to lack of dependencies.
To avoid this, we have two options listed below.
- Specify any Jar files in not only ${project.basedir}/target but also any subdirectories of ${project.basedir}/target as the deployment target.
<deployment>
<resources>
<resource>
<directory>${project.basedir}/target</directory>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
</resources>
</deployment>
2. Explicitly add /libs/*.jar as the additional deployment target.
<deployment>
<resources>
<resource>
<directory>${project.basedir}/target</directory>
<includes>
<include>*.jar</include>
<include>/libs/*.jar</include>
</includes>
</resource>
</resources>
</deployment>
Indeed we can use “maven assembly plugin” to generate an executable jar file that contains all dependencies. However, Helidon MP application does not always have a main method in the application, so it is sometimes hard to generate an executable jar with the plugin. Therefore, I recommend you copy all dependencies to Azure App Service.
Technically, the main class is not needed unless you want to control the startup sequence. You can set the
mainClass
toio.helidon.microprofile.Main
and it will find the application annotated withApplicationScoped
. 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
Server listening port
The following passage in the document says App service waits for incoming requests to 80/tcp.
App Service Linux routes incoming requests to port 80, so your application should listen on port 80 as well. You can do this in your application’s configuration (such as Spring’s application.properties file), or in your Startup Command (for example,
java -jar spring-app.jar --server.port=80
). Please see the following documentation for common Java frameworks:Server Port
https://docs.microsoft.com/azure/app-service/containers/configure-language-java#server-port
As default listening port of both SE and MP is not 80/tcp but 8080/tcp, we have two options listed below (If deploying Helidon based applications as Docker containers, we can use port binding to meet this requirement).
- Bind ports in order to use default port of Helidon quickstart application.
- Modify the listening port in order to meet Azure App Service requirements.
Port binding
Add property in appSettings section (in pom.xml) to specify bound ports as follows.
<configuration>
...
<appSettings>
<property>
<name>PORT</name>
<value>8080</value>
</property>
<property>
<name>WEBSITES_PORT</name>
<value>8080</value>
</property>
</appSettings>
...
</configuration>
Modifying port (Helidon SE)
Modify the value of server.port in resources/application.yaml. (Default value is 8080).
app:
greeting: "Hello"server:
port: 80
host: 0.0.0.0
Modifying port (Helidon MP)
Modify the value of server.port in META-INF/microprofile-config.properties. (Default value is 8080).
# Application properties. This is the default greeting
app.greeting=Hello
# Microprofile server properties
server.port=80
server.host=0.0.0.0
Build and deploy
We have to recognize privilege port related error might happen when the listening port is set to not 8080/tcp but 80/tcp. If needed, skip the test phase.
mvn package
When deploying the application to Azure App Service, use the following command (mvn azure-webapp:deploy).
mvn azure-webapp:deploy
As this deployment operation requires authentication against Azure, we have to complete authentication and authorization against Azure via Azure CLI in advance.
# Authentication and authorization with Azure CLI
az login# In case of multiple subscriptions, you should specify subscription ID.
az account set -s "subscription ID or subscription name"# Deploy!
mvn azure-webapp:deploy
Disabling FTP
Unless permitting deploying artifacts via FTP or FTPS, you should disable FTP/FTPS for security reasons.
Azure Portal : Settings > Configuration > General settings
Please make sure you save modified configuration.
(Optional) Confirming deployments via SSH
*** This operation is only for checking deployments purpose. ***
We can access inside of App Service container via SSH to check Jar files deployed to Azure. Open Azure Portal and select SSH in Development Tools.
Change the current directory to /home/site/wwwroot (deployment target directory), and we can see the following points.
- app.jar, which is renamed from either helidon-quickstart-se.jar or helidon-quickstart-mp.jar, exists in /home/site/wwwroot.
- Dependency Jar files exist in /home/site/www/root/libs.
Test
When calling GET /greet/{name} (http://<Azure App Service URL>/greet/Taro1), the following response comes back.
Conclusion
In this article, I described how to deploy Helidon applications to Azure App Service. I hope this article helps.