Using Azure Container Registry to build Docker images for Java projects

Published Jul 31 2022 05:14 AM 1,737 Views
Microsoft

In this article we will create a Docker image from a Java project using Azure Container Registry and then it will be deployed in a Docker compatible hosting environment, for instance Azure Container App. The image building will happen in Azure Container Registry, so it is NOT required docker in the development environment.

For this process it is required:

  • JDK 1.8+
  • Maven
  • Azure CLI
  • GIT

And the following Azure resources:

  • Azure Container Registry
  • Azure Container App. This resource can be changed by other container hosting service, such as Azure App Service, Azure Functions or Azure Kubernetes Service.

These Azure resources can be create using the following az cli commands:

 

LOCATION=westeurope
RESOURCE_GROUP=rg-acrbuild-demo
ACR_NAME=acrbuilddemo
CONTAINERAPPS_ENVIRONMENT=containerapp-demo
CONTAINERAPPS_NAME=spring-petclinic
# create a resource group to hold resources for the demo
az group create --location $LOCATION --name $RESOURCE_GROUP
# create an Azure Container Registry (ACR) to hold the images for the demo
az acr create --resource-group $RESOURCE_GROUP --name $ACR_NAME --sku Standard --location $LOCATION

# register container apps extension
az extension add --name containerapp --upgrade
# register Microsoft.App namespace provider
az provider register --namespace Microsoft.App
# create an azure container app environment
az containerapp env create \
    --name $CONTAINERAPPS_ENVIRONMENT \
    --resource-group $RESOURCE_GROUP \
    --location $LOCATION

# Create a user managed identity and assign AcrPull role on the ACR.
USER_IDENTITY=$(az identity create -g $RESOURCE_GROUP -n $CONTAINERAPPS_NAME --location $LOCATION --query clientId -o tsv)
ACR_RESOURCEID=$(az acr show --name $ACR_NAME --resource-group $RESOURCE_GROUP --query "id" --output tsv)
az role assignment create \
    --assignee "$USER_IDENTITY" --role AcrPull --scope "$ACR_RESOURCEID"

# container app will be created once the image is pushed to the ACR

 

Let's take a sample application, for instance the well known spring pet clinic.

 

git clone https://github.com/spring-projects/spring-petclinic.git
cd spring-petclinic

 

Then create a Dockerfile. For demo purposes it will be as simple as possible.

 

FROM openjdk:8-jdk-slim
# takes the jar file as an argument
ARG ARTIFACT_NAME
# assumes the application entry port is 8080
EXPOSE 8080

# The application's jar file
ARG JAR_FILE=${ARTIFACT_NAME}

# Add the application's jar to the container
ADD ${JAR_FILE} app.jar

# Run the jar file
ENTRYPOINT ["java","-jar","/app.jar"]

 

To build it locally the following command would be used, but as mentioned, it won't be necessary:

 

docker build -t myacr.azurecr.io/spring-petclinic:2.7.0 \
    -f Dockerfile \
    --build-arg ARTIFACT_NAME=target/spring-petclinic-2.7.0-SNAPSHOT.jar \
    .

 

As Azure Container Registry will be used to build the image, the following command would be used instead:

 

az acr build \
        --resource-group rg-spring-petclinic \
        --registry myacr \
        --image spring-petclinic:2.7.0 \
        --build-arg ARTIFACT_NAME=target/spring-petclinic-2.7.0-SNAPSHOT.jar \
        .

 

Instead of execute it manually, this command can be integrated as part of the maven build cycle. To perform this action, we will use 

org.codehaus.mojo:exec-maven-plugin. This plugin allows to execute system or Java programs. It will be used to execute the previous az cli command. To include as part of the build lifecycle it will be created a new maven profile.
<profile>
    <id>buildAcr</id>
    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>3.0.0</version>
                <executions>
                    <execution>
                        <id>acr-package</id>
                        <phase>package</phase>
                        <goals>
                            <goal>exec</goal>
                        </goals>
                        <configuration>
                            <executable>az</executable>
                            <workingDirectory>${project.basedir}</workingDirectory>
                            <arguments>
                                <argument>acr</argument>
                                <argument>build</argument>
                                <argument>--resource-group</argument>
                                <argument>${RESOURCE_GROUP}</argument>
                                <argument>--registry</argument>
                                <argument>${ACR_NAME}</argument>
                                <argument>--image</argument>
                                <argument>${project.artifactId}:${project.version}</argument>
                                <argument>--build-arg</argument>
                                <argument>ARTIFACT_NAME=target/${project.build.finalName}.jar</argument>
                                <argument>-f</argument>
                                <argument>Dockerfile</argument>
                                <argument>.</argument>
                            </arguments>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</profile>
To execute this process just execute the following maven goal with the new profile.
mvn package -PbuildAcr -DRESOURCE_GROUP=$RESOURCE_GROUP -DACR_NAME=$ACR_NAME

The resource group and the Azure Container Registry are passed as environment variables, but the can be defined as maven parameters or just hardcoding.

Now the image already exists in Azure Container Registry.

fmiguel_0-1656887311912.pngNow it's time to create the Container App.
# Create the container app
az containerapp create \
    --name ${CONTAINERAPPS_NAME} \
    --resource-group $RESOURCE_GROUP \
    --environment $CONTAINERAPPS_ENVIRONMENT \
    --container-name spring-petclinic-container \
    --user-assigned ${CONTAINERAPPS_NAME} \
    --registry-server $ACR_NAME.azurecr.io \
    --image $ACR_NAME.azurecr.io/spring-petclinic:2.7.0-SNAPSHOT \
    --ingress external \
    --target-port 8080 \
    --cpu 1 \
    --memory 2 
Now the application is deployed and running on Azure Container Apps.
fmiguel_0-1656974193359.png
fmiguel_1-1656974290151.png
You can find the source code for this application here.
Co-Authors
Version history
Last update:
‎Aug 05 2022 04:07 AM
Updated by: