DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
The Latest "Software Integration: The Intersection of APIs, Microservices, and Cloud-Based Systems" Trend Report
Get the report
  1. DZone
  2. Software Design and Architecture
  3. Cloud Architecture
  4. Tutorial: Deploying Java EE Apps on Azure (Part 2)

Tutorial: Deploying Java EE Apps on Azure (Part 2)

Run your Java EE app in a Docker container on Azure Container Instances

Abhishek Gupta user avatar by
Abhishek Gupta
CORE ·
Aug. 07, 20 · Tutorial
Like (5)
Save
Tweet
Share
8.42K Views

Join the DZone community and get the full member experience.

Join For Free

This is the second blog in a series that will walk you through the options of running Java EE applications on Azure. The first part provided details on how to deploy a Java EE app to an application server which is set up in a Virtual Machine on Microsoft Azure along with the Azure Database for PostgreSQL service as the backend database.

In this part, we will run the Java EE app as a Docker container on Azure Container Instances. The example used in the blog post is a simple three-tier application that uses Java EE 8 specifications, such as JAX-RS, EJB, CDI, JPA, JSF, Bean Validation. We will use the Payara Server to deploy the application and use PostgreSQL as the relational database.

During the course of the tutorial, we will cover:

  • Postgres setup on Azure.
  • Dockerize the Java EE app and setup Azure Container Registry to store the Docker image.
  • Deploy the application to Azure Container Instances.
  • Explore its functionality.

Except for minor changes, the application used in this tutorial has been adapted from this project by Reza Rahman

Prerequisites

You will need a Microsoft Azure account and the Azure CLI to work through the tutorial.

If you don't have a Microsoft Azure account, go ahead and sign up for a free one!. The Azure CLI is a cross-platform command-line experience for managing Azure resources - please intall it using these instructions.

First Things First...

Set your Azure Subscription ID using the Azure CLI which will be used for this tutorial.

To set your Azure subscription ID

Shell
xxxxxxxxxx
1
 
1
export AZURE_SUBSCRIPTION_ID=[to be filled]
2
az account set --subscription $AZURE_SUBSCRIPTION_ID


Create a resource group that will contain all the services (resources) which you will create as a part of this tutorial. A resource group is like a logical container that holds related resources for an Azure solution. The resource group includes those resources that you want to manage as a group.

To create a resource group

Shell
xxxxxxxxxx
1
 
1
export AZURE_RESOURCE_GROUP_NAME=[to be filled]
2
export AZURE_LOCATION=[to be filled]
3
az group create --name $AZURE_RESOURCE_GROUP_NAME --location $AZURE_LOCATION

Install Postgres on Azure

Azure Database for PostgreSQL is a relational database service based on the open-source Postgres database engine. It's a fully managed database-as-a-service offering which is available in two deployment options, as a single server and as a Hyperscale (Citus) cluster

We will be using the single server option for the purposes of this tutorial

We will use the az postgres server create command to create a Postgres server instance on Azure. First, set up some of the server properties such as the name, admin user etc.

Shell
xxxxxxxxxx
1
 
1
export AZURE_POSTGRES_SERVER_NAME=[to be filled]
2
export AZURE_POSTGRES_ADMIN_USER=[to be filled]
3
export AZURE_POSTGRES_ADMIN_PASSWORD=[to be filled]
4
export SKU=B_Gen5_1
5
export STORAGE=5120

For storage and SKU options, please refer to the documentation

And, then invoke the command to initiate the database instance creation:

Shell
xxxxxxxxxx
1
 
1
az postgres server create --resource-group $AZURE_RESOURCE_GROUP_NAME --name $AZURE_POSTGRES_SERVER_NAME  --location $AZURE_LOCATION --admin-user $AZURE_POSTGRES_ADMIN_USER --admin-password $AZURE_POSTGRES_ADMIN_PASSWORD --storage-size $STORAGE --sku-name $SKU


The provisioning process will take a few minutes.

To check the details of the Postgres database instance you just provisioned, invoke az postgres server show command:

Shell
xxxxxxxxxx
1
 
1
az postgres server show --resource-group $AZURE_RESOURCE_GROUP_NAME --name $AZURE_POSTGRES_SERVER_NAME


You should get a JSON response. Please note down the value for the fullyQualifiedDomainName attribute as you will be using this to connect to the Postgres instance later.

It should be of the format: [AZURE_POSTGRES_DB_NAME].postgres.database.azure.com

Allow Azure Container Instances to Access the Postgres Database

Later in the post, we will see how to deploy the application to Azure Container Instances. But, the Postgres database is not accessible to external services by default. We will use the az postgres server firewall-rule create command to create a firewall rule to explicitly allow Azure services to access the Postgres instance. This will allow the JavaEE application deployed within Azure Container Instances to communicate with Postgres.

Shell
xxxxxxxxxx
1
 
1
export FIREWALL_RULE_NAME=AllowJavaEECafeAppOnACI
2
3
az postgres server firewall-rule create --resource-group $AZURE_RESOURCE_GROUP_NAME --server-name $AZURE_POSTGRES_SERVER_NAME --start-ip-address=0.0.0.0 --end-ip-address=0.0.0.0 --name $FIREWALL_RULE_NAME

Note: This setting allows network connections from all IPs within the Azure network. For production use, try to configure the most restrictive firewall rules possible

Setup Azure Container Registry

Azure Container Registry is a managed, private Docker registry service to store and manage your private Docker container images (it based on the open-source Docker Registry 2.0). You can use Azure container registries with your existing container development and deployment pipelines, or use Azure Container Registry Tasks to build container images in Azure. Yo can either build on demand, or fully automate builds with triggers such as source code commits and base image updates.

Let's create a registry to store the Docker image for the JavaEE application. We will use the az acr create command:

Shell
xxxxxxxxxx
1
 
1
export ACR_NAME=javaeecafe-acr
2
az acr create --resource-group $AZURE_RESOURCE_GROUP_NAME --name $ACR_NAME --sku Basic --admin-enabled true

We are using the Basic SKU. Valid value are: Basic, Classic, Premium, Standard

You can login to the registry once it's created and check the login server

Shell
xxxxxxxxxx
1
 
1
az acr login --name $ACR_NAME
2
az acr show --name $ACR_NAME --query loginServer --output table

You will use the ACR login server name soon. It's value follows the format: [ACR_NAME].azurecr.io

Setup and Prepare Application Image

Now that we the have the VM as well as Payara server up and running, we can now deploy our application! Clone the git repository:

Shell
xxxxxxxxxx
1
 
1
git clone https://github.com/abhirockzz/javaee-on-azure-caas
2
cd javaee-on-azure-caas


You need to enter the Postgres connectivity information to the <url> attribute of the <data-source section in web.xml.

You can find the web.xml file under javaee-on-azure-iaas/src/main/webapp/WEB-INF

The format is as follows:

Plain Text
xxxxxxxxxx
1
 
1
jdbc:postgresql://[POSTGRES_FQDN]:5432/postgres?user=[AZURE_POSTGRES_ADMIN_USER]@[AZURE_POSTGRES_SERVER_NAME]&password=[AZURE_POSTGRES_ADMIN_PASSWORD]&sslmode=require


Here is the list placeholders which form a part of the JDBC URL:

  • POSTGRES_FQDN with value of fullyQualifiedDomainName
  • AZURE_POSTGRES_ADMIN_USER with admin user name used to provision PG
  • AZURE_POSTGRES_SERVER_NAME with server name used to provision PG
  • AZURE_POSTGRES_ADMIN_PASSWORD with admin password used to provision PG

Set the required values

Shell
xxxxxxxxxx
1
 
1
export POSTGRES_FQDN=
2
export AZURE_POSTGRES_ADMIN_USER=
3
export AZURE_POSTGRES_SERVER_NAME=
4
export AZURE_POSTGRES_ADMIN_PASSWORD=


Simply use these commands to replace

Shell
xxxxxxxxxx
1
 
1
export FILE_NAME=javaee-on-azure-iaas/src/main/webapp/WEB-INF/web.xml
2
3
sed -i 's/POSTGRES_FQDN/'"$POSTGRES_FQDN"'/g' $FILE_NAME
4
sed -i 's/AZURE_POSTGRES_SERVER_NAME/'"$AZURE_POSTGRES_SERVER_NAME"'/g' $FILE_NAME
5
sed -i 's/AZURE_POSTGRES_ADMIN_USER/'"$AZURE_POSTGRES_ADMIN_USER"'/g' $FILE_NAME
6
sed -i 's/AZURE_POSTGRES_ADMIN_PASSWORD/'"$AZURE_POSTGRES_ADMIN_PASSWORD"'/g' $FILE_NAME


Here is an e.g. of what the <data-source> section will look like:

XML
x
 
1
<data-source>
2
    <name>java:global/JavaEECafeDB</name>
3
    <class-name>org.postgresql.ds.PGPoolingDataSource</class-name>
4
    <url>
5
      jdbc:postgresql://foobar-pg.postgres.database.azure.com:5432/postgres
6
      user=foobar@foobar-pg&password=foobarbaz&sslmode=require
7
    </url>
8
</data-source>


The application is now configured. Let's build it!

Shell
xxxxxxxxxx
1
 
1
mvn clean install


You should have the WAR file available. To confirm

Shell
xxxxxxxxxx
1
 
1
ls -lrt target | grep javaee-cafe.war

Build and Push Image to Azure Container Registry

Our application artifact (WAR file) is ready. We can now build the Docker image and push it out to Azure Container Registry. Here is a quick look at the Dockerfile used for this

Dockerfile
xxxxxxxxxx
1
 
1
FROM payara/server-full
2
COPY target/javaee-cafe.war $DEPLOY_DIR
3
RUN wget https://jdbc.postgresql.org/download/postgresql-42.2.8.jar
4
RUN cp /opt/payara/postgresql-42.2.8.jar ${PAYARA_DIR}/glassfish/domains/${DOMAIN_NAME}/lib && rm /opt/payara/postgresql-42.2.8.jar
5
EXPOSE 8080


It builds on top of the base image for payara/server-full, copies the WAR file to a folder from where it can be automatically detected and deployed, downloads the Postgres JDBC driver and places it in the appropriate location for the Payara application server. That's it!

Shell
xxxxxxxxxx
1
 
1
export DOCKER_IMAGE=javaee-cafe
2
docker build -t $DOCKER_IMAGE .
3
docker tag $DOCKER_IMAGE $ACR_NAME.azurecr.io/$DOCKER_IMAGE


To push the image

Shell
xxxxxxxxxx
1
 
1
docker push $ACR_NAME.azurecr.io/$DOCKER_IMAGE


Use az acr repository list command to check the image.

Shell
xxxxxxxxxx
1
 
1
az acr repository list --name $ACR_NAME --output table

Deploy the Application to Azure Container Instances

Azure Container Instances allows you to run a container in Azure, without having to manage any VMs and or adopt a higher-level service. It is a solution for any scenario that can operate in isolated containers, including simple applications, task automation, and build jobs. For scenarios where you need full container orchestration, including service discovery across multiple containers, automatic scaling, and coordinated application upgrades, please take a look at Azure Kubernetes Service (AKS).

We are now ready to deploy the JavaEE application to Azure Container Instances. When you create a container instance, you can specify a custom DNS name label so your application is reachable at customlabel.azureregion.azurecontainer.io.

Shell
xxxxxxxxxx
1
 
1
export ACI_CONTAINER_NAME=javaee-cafe
2
export DNS_NAME_LABEL=javaee-cafe


We will need the password for Azure Container Registry to run our Docker image in Azure Container Instance.

Shell
xxxxxxxxxx
1
 
1
az acr credential show --name $ACR_NAME


Enter below command to create the container and enter the password (obtained above) when prompted:

Shell
xxxxxxxxxx
1
 
1
az container create --resource-group $AZURE_RESOURCE_GROUP_NAME --name $ACI_CONTAINER_NAME --image $ACR_NAME.azurecr.io/$DOCKER_IMAGE --dns-name-label $DNS_NAME_LABEL --registry-username $ACR_NAME --ports 8080

--ports 8080 ensures that we can access the application from port 8080. This is because Payara application server serves HTTP traffic on port 8080 by default.

The deployment will take sometime. In the meanwhile, you can track the logs using:

Shell
xxxxxxxxxx
1
 
1
az container attach -g $AZURE_RESOURCE_GROUP_NAME -n $ACI_CONTAINER_NAME


You should see log messages indicating successful deployment of the javaee-cafe application:

Plain Text
 
xxxxxxxxxx
1
 
1
[yyyy-mm-ddT13:34:21.317+0000] [Payara 5.193] [INFO] [NCLS-DEPLOYMENT-02035] [javax.enterprise.system.tools.deployment.autodeploy] [tid: _ThreadID=104 _ThreadName=payara-executor-service-scheduled-task] [timeMillis: 1574084061317] [levelValue: 800] [[
2
[AutoDeploy] Successfully autodeployed : /home/abhishgu/payara5/glassfish/domains/domain1/autodeploy/javaee-cafe.war.]]

Explore the Application

Access the JSF front end

Use your browser to access http://[APP_FQDN]:8080/javaee-cafe. You can use the UI to create, delete and see coffees.

The APP_FQDN is nothing but the combination of the DNS label and the Azure region e.g. http://javaee-cafe.southeastasia.azurecontainer.io:8080/javaee-cafe

Use the REST API

The application also exposes a REST API for creating, deleting and listing coffees.

Shell
xxxxxxxxxx
1
 
1
export JAVAEE_ACI_REST=http://javaee-cafe.southeastasia.azurecontainer.io:8080/javaee-cafe/rest/coffees


Create coffees

Shell
xxxxxxxxxx
1
 
1
curl -X POST $JAVAEE_ACI_REST:8080/javaee-cafe/rest/coffees -d '{"name":"cappuccino","price":"10"}' -H "Content-Type: application/json"
2
curl -X POST $JAVAEE_ACI_REST:8080/javaee-cafe/rest/coffees -d '{"name":"caffe-latte","price":"15"}' -H "Content-Type: application/json"


Get all coffees

Shell
xxxxxxxxxx
1
 
1
curl -H "Accept: application/json" $JAVAEE_ACI_REST:8080/javaee-cafe/rest/coffees


You should see a JSON response listing both the coffee options you just added

Get a coffee by ID

Shell
xxxxxxxxxx
1
 
1
curl -H "Accept: application/json" $JAVAEE_ACI_REST:8080/javaee-cafe/rest/coffees/1


Delete a coffee by ID

Shell
xxxxxxxxxx
1
 
1
curl -X DELETE $JAVAEE_ACI_REST:8080/javaee-cafe/rest/coffees/1
2
curl -H "Accept: application/json" $JAVAEE_ACI_REST:8080/javaee-cafe/rest/coffees


Notice that cappuccino is now deleted

Clean Up Resources

Once you are done exploring the application, you can delete the resources. Since we used a resource group, its easy executing a single command.

Please be aware that this will delete all the resources in the group which includes the ones you created as part of the tutorial (VM, Postgres etc.) as well as any other service instances you might have if you used an already existing resource group

Shell
xxxxxxxxxx
1
 
1
az group delete --name $AZURE_RESOURCE_GROUP_NAME

Summary

You learned how to leverage Docker containers to package and deploy the application to Azure Container Instances along with a managed database offering for long term persistence.

Stay tuned for part 3!

azure Docker (software) Kubernetes Java EE application shell app Java (programming language) PostgreSQL Relational database

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Building Microservice in Golang
  • Introduction to Container Orchestration
  • NoSQL vs SQL: What, Where, and How
  • DevOps for Developers: Continuous Integration, GitHub Actions, and Sonar Cloud

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: