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 on Open Liberty, see the Open Liberty project page. For more information on 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.53.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 or later - for example, Microsoft build of OpenJDK.
- Install Maven 3.5.0 or higher.
- Install Docker for your OS.
- Ensure that Git is installed.
Sign in to Azure
If you haven't done so already, 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 eastus 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 eastus
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.
export REGISTRY_NAME=youruniqueacrname
az acr create \
--resource-group $RESOURCE_GROUP_NAME \
--name $REGISTRY_NAME \
--sku Basic \
--admin-enabled
After a short time, you should see a JSON output that contains the following lines:
"provisioningState": "Succeeded",
"publicNetworkAccess": "Enabled",
"resourceGroup": "java-liberty-project",
Connect to the ACR instance
You need to sign in to the ACR instance before you can push an image to it. If you choose to run commands locally, ensure the docker daemon is running, and run the following commands to verify the connection:
export ACR_LOGIN_SERVER=$(az acr show \
--resource-group $RESOURCE_GROUP_NAME \
--name $REGISTRY_NAME \
--query 'loginServer' \
--output tsv)
export ACR_USER_NAME=$(az acr credential show \
--resource-group $RESOURCE_GROUP_NAME \
--name $REGISTRY_NAME \
--query 'username' \
--output tsv)
export ACR_PASSWORD=$(az acr credential show \
--resource-group $RESOURCE_GROUP_NAME \
--name $REGISTRY_NAME \
--query 'passwords[0].value' \
--output tsv)
docker login $ACR_LOGIN_SERVER -u $ACR_USER_NAME -p $ACR_PASSWORD
You should see Login Succeeded
at the end of command output if you've logged into the ACR instance successfully.
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 \
--location eastus \
--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.
Create a single database in Azure SQL Database by following the Azure CLI steps in Quickstart: Create a single database - Azure SQL Database. Execute the steps up to, but not including Query the database. Use the following steps as you go through the article, then return to this document after you create and configure the database server:
When you reach the Set parameter values section of the quickstart, output and save aside the values of variables in the code example labeled Variable block
, including resourceGroup
,server
, database
, login
, and password
. Define the following environment variables after replacing placeholders <resourceGroup>
,<server>
, <database>
, <login>
, and <password>
with these values.
export DB_RESOURCE_GROUP=<resourceGroup>
export DB_SERVER_NAME=<server>.database.windows.net
export DB_NAME=<database>
export DB_USER=<login>
export DB_PASSWORD=<password>
If you want to test the application locally later, use the following steps to ensure your client IPv4 address is allowed to connect:
In the portal, search for and select SQL databases, and then select your database from the list.
Select Overview.
Ensure the Getting started tab is selected in the middle of the page.
Under Configure access, select Configure.
Select Add your client IPv4 address.
Select Save.
You can find and configure Firewall rules in the Networking pane and Public access tab.
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
git checkout 20231026
If you see a message about being in detached HEAD
state, this message is safe to ignore. It just means you have checked out a tag.
This article uses java-app. Here's the file structure of the application:
java-app
├─ src/main/
│ ├─ liberty/config/
│ │ ├─ server.xml
│ ├─ java/
│ ├─ resources/
│ ├─ webapp/
├─ Dockerfile
├─ Dockerfile-wlp
├─ pom.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 file is used to configure the DB connection for the Open Liberty and WebSphere Liberty cluster.
Build the project
Use the following command to build the application:
cd <path-to-your-repo>/java-app
mvn clean install
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.
(Optional) 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
.liberty:run
uses the database related environment variables defined in the previous step.cd <path-to-your-repo>/java-app mvn liberty:run
Verify the application works as expected. You should see a message similar to
[INFO] [AUDIT] CWWKZ0003I: The application javaee-cafe updated in 1.930 seconds.
in the command output if successful. Go tohttp://localhost:9080/
in your browser to verify the application is accessible and all functions are working.Press Ctrl+C to stop.
Build the image
You can now run the docker buildx build
command to build the image, as shown in the following example:
cd <path-to-your-repo>/java-app
# If you are running with Open Liberty
docker buildx build --platform linux/amd64 -t javaee-cafe:v1 --pull --file=Dockerfile .
# If you are running with WebSphere Liberty
docker buildx build --platform linux/amd64 -t javaee-cafe:v1 --pull --file=Dockerfile-wlp .
(Optional) Test the Docker image locally
You can now use the following steps to test the Docker image locally before deploying to Azure:
Run the image using the following command. This command uses the database related environment variables defined previously.
docker run -it --rm -p 9080:9080 \ -e DB_SERVER_NAME=${DB_SERVER_NAME} \ -e DB_NAME=${DB_NAME} \ -e DB_USER=${DB_USER} \ -e DB_PASSWORD=${DB_PASSWORD} \ javaee-cafe:v1
After the container starts, go to
http://localhost:9080/
in your browser to access the application.Press Ctrl+C to stop.
Upload image to ACR
Next, upload the built image to the ACR you created in the previous steps.
If you haven't already done so, use the following command to sign in to the ACR:
docker login -u ${ACR_USER_NAME} -p ${ACR_PASSWORD} ${ACR_LOGIN_SERVER}
Use the following commands to tag and push the container image:
docker tag javaee-cafe:v1 ${ACR_LOGIN_SERVER}/javaee-cafe:v1
docker push ${ACR_LOGIN_SERVER}/javaee-cafe:v1
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-username $ACR_USER_NAME \
--registry-password $ACR_PASSWORD \
--target-port 9080 \
--env-vars \
DB_SERVER_NAME=${DB_SERVER_NAME} \
DB_NAME=${DB_NAME} \
DB_USER=${DB_USER} \
DB_PASSWORD=${DB_PASSWORD} \
--ingress 'external'
Successful output is a JSON object including the property "type": "Microsoft.App/containerApps"
.
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
az group delete --name $DB_RESOURCE_GROUP --yes --no-wait
Then, use the following command to remove the container image from your local Docker server:
docker rmi -f ${ACR_LOGIN_SERVER}/javaee-cafe:v1
Next steps
You can learn more from the references used in this guide:
- Azure Container Apps
- 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?