Deploy a Java application with Open Liberty or WebSphere Liberty on Azure Container Apps
This article shows you how to run Open Liberty or WebSphere Liberty on Azure Container Apps. You do the following activities in this article:
- Run your Java, Java EE, Jakarta EE, or MicroProfile application on the Open Liberty or WebSphere Liberty runtime.
- Build the application Docker image using Liberty container images.
- Deploy the containerized application to Azure Container Apps.
For more information about Open Liberty, see the Open Liberty project page. For more information about IBM WebSphere Liberty, see the WebSphere Liberty product page.
This article is intended to help you quickly get to deployment. Before going to production, you should explore Tuning Liberty.
If you're interested in providing feedback or working closely on your migration scenarios with the engineering team developing WebSphere on Azure solutions, fill out this short survey on WebSphere migration and include your contact information. The team of program managers, architects, and engineers will promptly get in touch with you to initiate close collaboration.
Prerequisites
- An Azure subscription. If you don't have an Azure subscription, create a free account before you begin.
- Prepare a local machine with either Windows or Unix-like operating system installed - for example, Ubuntu, macOS, or Windows Subsystem for Linux.
- Install the Azure CLI 2.62.0 or above to run Azure CLI commands.
- Sign in with Azure CLI by using the az login command. To finish the authentication process, follow the steps displayed in your terminal. See Sign into Azure with Azure CLI for other sign-in options.
- When you're prompted, install the Azure CLI extension on first use. For more information about extensions, see Use and manage extensions with the Azure CLI.
- Run az version to find the version and dependent libraries that are installed. To upgrade to the latest version, run az upgrade.
- Install a Java SE implementation version 17 - for example, Microsoft build of OpenJDK.
- Install Maven 3.9.8 or higher.
- Ensure that Git is installed.
Sign in to Azure
Sign in to your Azure subscription by using the az login command and follow the on-screen directions.
az login
Note
You can run most Azure CLI commands in PowerShell the same as in Bash. The difference exists only when using variables. In the following sections, the difference is addressed in different tabs when needed.
If you have multiple Azure tenants associated with your Azure credentials, you must specify which tenant you want to sign in to. You can do this with the --tenant
option - for example, az login --tenant contoso.onmicrosoft.com
.
If you have multiple subscriptions within a single tenant, make sure you are signed in with the one you intend to use by using az account set --subscription <subscription-id>
.
Create a resource group
An Azure resource group is a logical group in which Azure resources are deployed and managed.
Create a resource group called java-liberty-project
using the az group create command in the eastus2
location. This resource group is used later for creating the Azure Container Registry (ACR) instance and the Azure Container Apps instance.
export RESOURCE_GROUP_NAME=java-liberty-project
az group create --name $RESOURCE_GROUP_NAME --location eastus2
Create an ACR instance
Use the az acr create command to create the ACR instance. The following example creates an ACR instance named youruniqueacrname
. Make sure youruniqueacrname
is unique within Azure.
Note
This article uses the recommended passwordless authentication mechanism for Container Registry. It's still possible to use username and password with docker login
after using az acr credential show
to obtain the username and password. Using username and password is less secure than passwordless authentication.
export REGISTRY_NAME=youruniqueacrname
az acr create \
--resource-group $RESOURCE_GROUP_NAME \
--name $REGISTRY_NAME \
--sku Basic
After a short time, you should see a JSON output that contains the following lines:
"provisioningState": "Succeeded",
"publicNetworkAccess": "Enabled",
"resourceGroup": "java-liberty-project",
Next, use the following command to retrieve the login server for the Container Registry instance. You need this value when you deploy the application image to the Azure Container Apps later.
export ACR_LOGIN_SERVER=$(az acr show \
--resource-group $RESOURCE_GROUP_NAME \
--name $REGISTRY_NAME \
--query 'loginServer' \
--output tsv)
Create an environment
An environment in Azure Container Apps creates a secure boundary around a group of container apps. Container Apps deployed to the same environment are deployed in the same virtual network and write logs to the same Log Analytics workspace. Use the az containerapp env create command to create an environment. The following example creates an environment named youracaenvname
:
export ACA_ENV=youracaenvname
az containerapp env create \
--resource-group $RESOURCE_GROUP_NAME \
--name $ACA_ENV
If you're asked to install an extension, answer Y.
After a short time, you should see a JSON output that contains the following lines:
"provisioningState": "Succeeded",
"type": "Microsoft.App/managedEnvironments"
"resourceGroup": "java-liberty-project",
Create an Azure SQL Database
In this section, you create an Azure SQL Database single database for use with your app.
First, use the following commands to set database-related environment variables. Replace <your-unique-sql-server-name>
with a unique name for your Azure SQL Database server.
export SQL_SERVER_NAME=<your-unique-sql-server-name>
export DB_NAME=demodb
Next, use the following commands to create a single database in Azure SQL Database and set the current signed-in user as a Microsoft Entra admin. For more information, see Quickstart: Create a single database - Azure SQL Database.
export ENTRA_ADMIN_NAME=$(az account show --query user.name --output tsv)
az sql server create \
--name $SQL_SERVER_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--enable-ad-only-auth \
--external-admin-principal-type User \
--external-admin-name $ENTRA_ADMIN_NAME \
--external-admin-sid $(az ad signed-in-user show --query id --output tsv)
az sql db create \
--resource-group $RESOURCE_GROUP_NAME \
--server $SQL_SERVER_NAME \
--name $DB_NAME \
--edition GeneralPurpose \
--compute-model Serverless \
--family Gen5 \
--capacity 2
Then, use the following command to add the local IP address to the Azure SQL Database server firewall rules to allow your local machine to connect to the database for local testing later.
export AZ_LOCAL_IP_ADDRESS=$(curl -s https://whatismyip.akamai.com)
az sql server firewall-rule create \
--resource-group $RESOURCE_GROUP_NAME \
--server $SQL_SERVER_NAME \
--name AllowLocalIP \
--start-ip-address $AZ_LOCAL_IP_ADDRESS \
--end-ip-address $AZ_LOCAL_IP_ADDRESS
Note
You create an Azure SQL server with SQL authentication disabled for security considerations. Only Microsoft Entra ID is used to authenticate to the server. If you need to enable SQL authentication, see az sql server create.
Configure and build the application image
To deploy and run your Liberty application on Azure Container Apps, containerize your application as a Docker image using Open Liberty container images or WebSphere Liberty container images.
Follow the steps in this section to deploy the sample application on the Liberty runtime. These steps use Maven.
Check out the application
Use the following commands to prepare the sample code for this guide. The sample is on GitHub.
git clone https://github.com/Azure-Samples/open-liberty-on-aca.git
cd open-liberty-on-aca
export BASE_DIR=$PWD
git checkout 20241118
If you see a message about being in detached HEAD
state, this message is safe to ignore. It just means you checked out a tag.
This article uses java-app. Here's the file structure of the application's important files:
java-app
├─ src/main/
│ ├─ liberty/config/
│ │ ├─ server.xml
│ ├─ java/
│ ├─ resources/
│ ├─ webapp/
├─ Dockerfile
├─ Dockerfile-wlp
├─ pom.xml
├─ pom-azure-identity.xml
The directories java, resources, and webapp contain the source code of the sample application. The code declares and uses a data source named jdbc/JavaEECafeDB
.
In the java-app root directory, there are two files to create the application image with either Open Liberty or WebSphere Liberty.
In directory liberty/config, the server.xml is used to configure the database connection for the Open Liberty and WebSphere Liberty cluster. It defines a variable azure.sql.connectionstring
that is used to connect to the Azure SQL Database.
The pom.xml file is the Maven project object model (POM) file that contains the configuration information for the project. The pom-azure-identity.xml file declares azure-identity
dependency, which is used to authenticate to Azure services using Microsoft Entra ID.
Note
This sample uses azure-identity
library to authenticate to Azure SQL Database using Microsoft Entra authentication, which is recommended for security considerations. If you need to use SQL authentication in your Liberty application, see Relational database connections with JDBC.
Build the project
Use the following command to build the application:
d $BASE_DIR/java-app
mvn clean install
mvn dependency:copy-dependencies -f pom-azure-identity.xml -DoutputDirectory=target/liberty/wlp/usr/shared/resources
If the build is successful, you should see output similar to the following at the end of your build.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 22.651 s
[INFO] Finished at: 2023-10-26T18:58:40-04:00
[INFO] ------------------------------------------------------------------------
If you don't see this output, troubleshoot and resolve the problem before continuing.
Test your project locally
You can now use the following steps to run and test the project locally before deploying to Azure. For convenience, use the liberty-maven-plugin
. To learn more about the liberty-maven-plugin
, see Building a web application with Maven. For your application, you can do something similar using any other mechanism, such as your local IDE.
Note
If you selected a "serverless" database deployment, verify that your SQL database has not entered pause mode. One way to do this is to log in to the database query editor as described in Quickstart: Use the Azure portal query editor (preview) to query Azure SQL Database.
Start the application using
liberty:run
.cd $BASE_DIR/java-app # The value of environment variable AZURE_SQL_CONNECTIONSTRING is read by configuration variable `azure.sql.connectionstring` in server.xml export AZURE_SQL_CONNECTIONSTRING="jdbc:sqlserver://$SQL_SERVER_NAME.database.windows.net:1433;databaseName=$DB_NAME;authentication=ActiveDirectoryDefault" mvn liberty:run
Verify that the application works as expected. If successful, you should see a message similar to
[INFO] [AUDIT ] CWWKZ0001I: Application javaee-cafe started in 11.086 seconds.
in the command output. Go tohttp://localhost:9080/
in your browser to verify that the application is accessible and all functions are working.Press Ctrl+C to stop. Select Y if you're asked to terminate the batch job.
When you're finished, delete the firewall rule that allows your local IP address to access the Azure SQL Database by using the following command:
az sql server firewall-rule delete \
--resource-group $RESOURCE_GROUP_NAME \
--server $SQL_SERVER_NAME \
--name AllowLocalIP
Build the image for Azure Container Apps deployment
You can now run the az acr build command to build the image, as shown in the following example:
cd $BASE_DIR/java-app
az acr build \
--registry ${REGISTRY_NAME} \
--image javaee-cafe:v1 \
.
The az acr build
command uploads the artifacts specified in the Dockerfile to the Container Registry instance, builds the image, and stores it in the Container Registry instance.
Deploy the application to Azure Container Apps
Use the following commands to create an Azure Container Apps instance to run the app after pulling the image from the ACR. This example creates an Azure Container Apps instance named youracainstancename
.
export ACA_NAME=youracainstancename
az containerapp create \
--resource-group $RESOURCE_GROUP_NAME \
--name $ACA_NAME \
--image ${ACR_LOGIN_SERVER}/javaee-cafe:v1 \
--environment $ACA_ENV \
--registry-server $ACR_LOGIN_SERVER \
--registry-identity system \
--target-port 9080 \
--ingress 'external' \
--min-replicas 1
Successful output is a JSON object including the property "type": "Microsoft.App/containerApps"
.
Then, connect the Azure SQL Database server to the container app using Service Connector by using the following steps:
This sample uses Service Connector to facilitate connecting to the database. For more information about Service Connector, see What is Service Connector? Install the passwordless extension for the Azure CLI by using the following command:
az extension add --name serviceconnector-passwordless --upgrade --allow-preview true
Connect the database to the container app with a system-assigned managed identity by using the following command:
az containerapp connection create sql \ --resource-group $RESOURCE_GROUP_NAME \ --name $ACA_NAME \ --target-resource-group $RESOURCE_GROUP_NAME \ --server $SQL_SERVER_NAME \ --database $DB_NAME \ --system-identity \ --container $ACA_NAME \ --client-type java
Successful output is a JSON object including the property
"type": "microsoft.servicelinker/linkers"
.
Note
The Service Connector creates a secret in the container app that contains the value for AZURE_SQL_CONNECTIONSTRING
, which is a password-free connection string to the Azure SQL Database. For more information, see the sample value from the User-assigned managed identity section of Integrate Azure SQL Database with Service Connector.
Test the application
Use the following command to get a fully qualified URL to access the application:
echo https://$(az containerapp show \
--resource-group $RESOURCE_GROUP_NAME \
--name $ACA_NAME \
--query properties.configuration.ingress.fqdn \
--output tsv)
Open a web browser to the URL to access and test the application. The following screenshot shows the running application:
Clean up resources
To avoid Azure charges, you should clean up unnecessary resources. When the cluster is no longer needed, use the az group delete command to remove the resource group, container registry, container apps, database server, and all related resources.
az group delete --name $RESOURCE_GROUP_NAME --yes --no-wait
Next steps
You can learn more from the references used in this guide:
- Azure Container Apps
- Integrate Azure SQL Database with Service Connector
- Connect using Microsoft Entra authentication
- Open Liberty
- Open Liberty Server Configuration
- Liberty Maven Plugin
- Open Liberty Container Images
- WebSphere Liberty Container Images
To explore options to run WebSphere products on Azure, see What are solutions to run the WebSphere family of products on Azure?