Implementación de una aplicación Java con Quarkus en una instancia de Azure Container Apps
En este artículo se muestra cómo implementar rápidamente Red Hat Quarkus en Microsoft Azure Container Apps con una sencilla aplicación CRUD. La aplicación es una "lista de tareas pendientes" con un front-end de JavaScript y un punto de conexión REST. Azure Database for PostgreSQL proporciona la capa de persistencia para la aplicación. En el artículo se muestra cómo probar la aplicación localmente e implementarla en Container Apps.
Requisitos previos
- Si no tiene una suscripción a Azure, cree una cuenta gratuita antes de empezar.
- Azure Cloud Shell tiene todos estos requisitos previos preinstalados. Para obtener más información, consulte Inicio rápido para Azure Cloud Shell.
- Si ejecuta los comandos de esta guía localmente (en lugar de usar Azure Cloud Shell), complete los pasos siguientes:
- Prepare una máquina local con un sistema operativo similar a Unix instalado (por ejemplo, Ubuntu, macOS o Subsistema de Windows para Linux).
- Instale una implementación de Java SE versión 17 o posterior (por ejemplo, microsoft build of OpenJDK).
- Instale Maven 3.5.0 o una versión superior.
- Instale Docker o Podman para el sistema operativo.
- Instale jq.
- Instale cURL.
- Instale la CLI de Quarkus 3.4.1 o posterior.
- CLI de Azure para entornos similares a Unix. En este artículo solo se requiere la variante bash de la CLI de Azure.
Instale la CLI de Azure e inicie sesión de forma interactiva con el comando az login para iniciar sesión en Azure antes de usar DefaultAzureCredential
en el código.az login
- Este artículo requiere al menos la versión 2.31.0 de la CLI de Azure. Si usa Azure Cloud Shell, ya está instalada la versión más reciente.
Crear el proyecto de la aplicación
Use el siguiente comando para clonar el proyecto de Java de ejemplo para este artículo. El ejemplo se encuentra en GitHub.
git clone https://github.com/Azure-Samples/quarkus-azure
cd quarkus-azure
git checkout 2023-09-13
cd aca-quarkus
Si ve un mensaje acerca de estar en estado HEAD desasociado, este mensaje es seguro de omitir. Dado que este artículo no requiere ninguna confirmación, el estado HEAD desasociado es adecuado.
Prueba local de la aplicación Quarkus
Los pasos de esta sección muestran cómo ejecutar la aplicación localmente.
Quarkus admite el aprovisionamiento automático de servicios no configurados en modo de desarrollo y prueba. Quarkus hace referencia a esta funcionalidad como servicios de desarrollo. Supongamos que incluye una característica de Quarkus, como conectarse a un servicio de base de datos. Quiere probar la aplicación, pero aún no ha configurado completamente la conexión a una base de datos real. Quarkus inicia automáticamente una versión de código auxiliar del servicio pertinente y conecta la aplicación a ella. Para obtener más información, consulte Información general de Dev Services en la documentación de Quarkus.
Asegúrese de que el entorno de contenedor, Docker o Podman, se está ejecutando y use el siguiente comando para especificar el modo de desarrollo de Quarkus:
quarkus dev
En lugar de quarkus dev
, puede lograr lo mismo con Maven mediante mvn quarkus:dev
.
Es posible que se le pregunte si desea enviar telemetría del uso del modo de desarrollo de Quarkus. Si es así, responda como quiera.
El modo de desarrollo de Quarkus habilita la recarga en vivo con la compilación en segundo plano. Si modifica algún aspecto del código fuente de la aplicación y actualiza el explorador, puede ver los cambios. Si hay algún problema con la compilación o la implementación, una página de error le informará. El modo de desarrollo de Quarkus escucha un depurador en el puerto 5005. Si desea esperar a que el depurador se adjunte antes de ejecutarse, pase -Dsuspend
en la línea de comandos. Si no quiere el depurador en absoluto, puede usar -Ddebug=false
.
La salida debería tener un aspecto similar al ejemplo siguiente:
__ ____ __ _____ ___ __ ____ ______
--/ __ \/ / / / _ | / _ \/ //_/ / / / __/
-/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
INFO [io.quarkus] (Quarkus Main Thread) quarkus-todo-demo-app-aca 1.0.0-SNAPSHOT on JVM (powered by Quarkus 3.2.0.Final) started in 14.826s. Listening on: http://localhost:8080
INFO [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
INFO [io.quarkus] (Quarkus Main Thread) Installed features: [agroal, cdi, hibernate-orm, hibernate-validator, jdbc-postgresql, narayana-jta, resteasy-reactive, resteasy-reactive-jackson, smallrye-context-propagation, vertx]
--
Tests paused
Press [e] to edit command line args (currently ''), [r] to resume testing, [o] Toggle test output, [:] for the terminal, [h] for more options>
Presione w en el terminal donde se está ejecutando el modo de desarrollo de Quarkus. La tecla w abre el explorador web predeterminado para mostrar la aplicación Todo
. También puede acceder a la GUI de la aplicación directamente en http://localhost:8080
.
Intente seleccionar algunos elementos de tareas pendientes en la lista de tareas pendientes. La interfaz de usuario indica la selección con un estilo de texto tachado. También puede agregar un nuevo elemento de tareas pendientes a la lista de tareas pendientes escribiendo Comprobar aplicaciones de tareas pendientes y presionando ENTRAR, como se muestra en la captura de pantalla siguiente:
Acceda a la API de RESTful (/api
) para obtener todos los elementos de tareas pendientes que se almacenan en la base de datos de PostgreSQL local:
curl --verbose http://localhost:8080/api | jq .
La salida debería tener un aspecto similar al ejemplo siguiente:
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /api HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.88.1
> Accept: */*
>
< HTTP/1.1 200 OK
< content-length: 664
< Content-Type: application/json;charset=UTF-8
<
{ [664 bytes data]
100 664 100 664 0 0 13278 0 --:--:-- --:--:-- --:--:-- 15441
* Connection #0 to host localhost left intact
[
{
"id": 1,
"title": "Introduction to Quarkus Todo App",
"completed": false,
"order": 0,
"url": null
},
{
"id": 2,
"title": "Quarkus on Azure App Service",
"completed": false,
"order": 1,
"url": "https://learn.microsoft.com/en-us/azure/developer/java/eclipse-microprofile/deploy-microprofile-quarkus-java-app-with-maven-plugin"
},
{
"id": 3,
"title": "Quarkus on Azure Container Apps",
"completed": false,
"order": 2,
"url": "https://learn.microsoft.com/en-us/training/modules/deploy-java-quarkus-azure-container-app-postgres/"
},
{
"id": 4,
"title": "Quarkus on Azure Functions",
"completed": false,
"order": 3,
"url": "https://learn.microsoft.com/en-us/azure/azure-functions/functions-create-first-quarkus"
},
{
"id": 5,
"title": "Verify Todo apps",
"completed": false,
"order": 5,
"url": null
}
]
Presione q para salir del modo de desarrollo de Quarkus.
Creación de los recursos de Azure para ejecutar la aplicación Quarkus
Los pasos de esta sección muestran cómo crear los siguientes recursos de Azure para ejecutar la aplicación de ejemplo Quarkus:
- Microsoft Azure Database for PostgreSQL
- Microsoft Azure Container Registry
- Aplicaciones de contenedor
Algunos de estos recursos deben tener nombres únicos dentro del ámbito de la suscripción de Azure. Para garantizar esta unicidad, puede usar el patrón de iniciales, secuencia, fecha y sufijo. Para aplicar este patrón, asigne un nombre a los recursos enumerando las iniciales, algún número de secuencia, la fecha de hoy y algún tipo de sufijo específico del recurso, por ejemplo, rg
para "grupo de recursos". Use los siguientes comandos para definir algunas variables de entorno para usarlas más adelante:
export UNIQUE_VALUE=<your unique value, such as ejb091223>
export RESOURCE_GROUP_NAME=${UNIQUE_VALUE}rg
export LOCATION=<your desired Azure region for deploying your resources. For example, eastus>
export REGISTRY_NAME=${UNIQUE_VALUE}reg
export DB_SERVER_NAME=${UNIQUE_VALUE}db
export DB_PASSWORD=Secret123456
export ACA_ENV=${UNIQUE_VALUE}env
export ACA_NAME=${UNIQUE_VALUE}aca
Creación de una instancia de Azure Database for PostgreSQL
Azure Database for PostgreSQL es un servicio administrado que usa para ejecutar, administrar y escalar bases de datos de PostgreSQL de alta disponibilidad en la nube. Esta sección le dirige a un inicio rápido independiente que muestra cómo crear un servidor único de Azure Database for PostgreSQL y conectarse a él. Sin embargo, cuando siga los pasos del inicio rápido, debe usar la configuración de la tabla siguiente para personalizar la implementación de la base de datos para la aplicación Quarkus de ejemplo. Reemplace las variables de entorno por sus valores reales al rellenar los campos en Azure Portal.
Configuración | valor | Descripción |
---|---|---|
Grupo de recursos | ${RESOURCE_GROUP_NAME} |
Seleccione Crear nuevo. La implementación crea este nuevo grupo de recursos. |
Nombre del servidor | ${DB_SERVER_NAME} |
Este valor forma parte del nombre de host del servidor de bases de datos. |
Ubicación | ${LOCATION} |
Seleccione una ubicación en la lista desplegable. Tome nota de la ubicación. Debe usar esta misma ubicación para otros recursos de Azure que cree. |
Nombre de usuario administrador | quarkus | El código de ejemplo supone este valor. |
Contraseña | ${DB_PASSWORD} |
La contraseña debe tener al menos 8 caracteres y, como máximo, 128 caracteres. La contraseña debe contener caracteres de tres de las siguientes categorías: letras en mayúsculas del alfabeto inglés, letras en minúscula del alfabeto inglés, números (0-9) y caracteres no alfanuméricos (!, $, #, %, etc.). La contraseña no puede contener todo o parte del nombre de inicio de sesión. Parte de un nombre de inicio de sesión se define como tres o más caracteres alfanuméricos consecutivos. |
Teniendo en cuenta estas sustituciones de valor, siga los pasos descritos en Inicio rápido: Creación de un servidor de Azure Database for PostgreSQL mediante el Azure Portal hasta la sección "Configurar una regla de firewall". A continuación, en la sección "Configurar una regla de firewall", asegúrese de seleccionar Sí para Permitir el acceso a los servicios de Azure y, a continuación, seleccione Guardar. Si no lo hace, la aplicación Quarkus no puede acceder a la base de datos y simplemente no se inicia nunca.
Después de completar los pasos del inicio rápido a través de la sección "Configuración de una regla de firewall", incluido el paso para permitir el acceso a los servicios de Azure, vuelva a este artículo.
Creación de una base de datos todo en Azure Database for PostgreSQL
El servidor de PostgreSQL que creó anteriormente está vacío. No tiene ninguna base de datos que pueda usar con la aplicación de Quarkus. Cree una nueva base de datos llamada todo
con el comando siguiente:
az postgres db create \
--resource-group ${RESOURCE_GROUP_NAME} \
--name todo \
--server-name ${DB_SERVER_NAME}
Debe usar todo
como nombre de la base de datos porque el código de ejemplo asume ese nombre para la base de datos.
Si el comando se ejecuta correctamente, la salida es similar al ejemplo siguiente:
{
"charset": "UTF8",
"collation": "English_United States.1252",
"id": "/subscriptions/REDACTED/resourceGroups/ejb091223rg/providers/Microsoft.DBforPostgreSQL/servers/ejb091223db/databases/todo",
"name": "todo",
"resourceGroup": "ejb091223rg",
"type": "Microsoft.DBforPostgreSQL/servers/databases"
}
Crear una instancia de Microsoft Azure Container Registry
Dado que Quarkus es una tecnología nativa en la nube, tiene compatibilidad integrada para crear contenedores que se ejecutan en Container Apps. Container Apps depende completamente de tener un registro de contenedor desde el que encuentra las imágenes de contenedor que se van a ejecutar. Container Apps tiene compatibilidad integrada con Azure Container Registry.
Use el comando az acr create para crear la instancia de Container Registry. En el ejemplo siguiente se crea una instancia de Container Registry denominada con el valor de la variable ${REGISTRY_NAME}
de entorno :
az acr create \
--resource-group $RESOURCE_GROUP_NAME \
--location ${LOCATION} \
--name $REGISTRY_NAME \
--sku Basic \
--admin-enabled
Tras un breve período de tiempo, debería ver una salida JSON que contiene las siguientes líneas:
"provisioningState": "Succeeded",
"publicNetworkAccess": "Enabled",
"resourceGroup": "<YOUR_RESOURCE_GROUP>",
Conectar docker a la instancia de Container Registry
Inicie sesión en la instancia de Container Registry. El inicio de sesión le permite insertar una imagen. Use los comandos siguientes para comprobar la conexión:
export LOGIN_SERVER=$(az acr show \
--name $REGISTRY_NAME \
--query 'loginServer' \
--output tsv)
echo $LOGIN_SERVER
export USER_NAME=$(az acr credential show \
--name $REGISTRY_NAME \
--query 'username' \
--output tsv)
echo $USER_NAME
export PASSWORD=$(az acr credential show \
--name $REGISTRY_NAME \
--query 'passwords[0].value' \
--output tsv)
echo $PASSWORD
docker login $LOGIN_SERVER -u $USER_NAME -p $PASSWORD
Si usa Podman en lugar de Docker, realice los cambios necesarios en el comando.
Si ha iniciado sesión correctamente en la instancia de Container Registry, debería ver Login Succeeded
al final de la salida del comando.
Creación de un entorno
Un entorno de Azure Container Apps crea un límite seguro alrededor de un grupo de aplicaciones de contenedor. Las aplicaciones de contenedor implementadas en el mismo entorno se implementan en la misma red virtual y escriben registros en la misma área de trabajo de Log Analytics. Use el comando az containerapp env create para crear un entorno, como se muestra en el ejemplo siguiente:
az containerapp env create \
--resource-group $RESOURCE_GROUP_NAME \
--location $LOCATION \
--name $ACA_ENV
Si se le pide que instale una extensión, responda a Y.
Personalización de la configuración nativa de la nube
Como tecnología nativa en la nube, Quarkus ofrece la capacidad de generar automáticamente imágenes de contenedor. Para obtener más información, consulte Imágenes de contenedor. A continuación, los desarrolladores pueden implementar la imagen de aplicación en una plataforma en contenedores de destino, por ejemplo, Azure Container Apps.
Para generar la imagen de contenedor, use el siguiente comando para agregar la extensión en el container-image-jib
terminal local:
quarkus ext add container-image-jib
Quarkus modifica el POM para asegurarse de que la extensión se incluye entre .<dependencies>
Si se le pide que instale algo llamado JBang
, responda sí y permita que se instale.
La salida debería tener un aspecto similar al ejemplo siguiente:
[SUCCESS] ✅ Extension io.quarkus:quarkus-container-image-jib has been installed
Para comprobar que se agregan las extensiones, puede ejecutar git diff
y examinar la salida.
Como tecnología nativa en la nube, Quarkus admite la noción de perfiles de configuración. Quarkus tiene los tres perfiles integrados siguientes:
dev
- Activado cuando está en modo de desarrollo.test
- Activado al ejecutar pruebas.prod
- Perfil predeterminado cuando no se ejecuta en modo de desarrollo o prueba.
Quarkus admite cualquier número de perfiles con nombre, según sea necesario.
Los pasos restantes de esta sección le dirigen a quitar la marca de comentario y personalizar los valores en el archivo src/main/resources/application.properties. Asegúrese de que todas las líneas que comienzan por # %prod.
estén sin la marca de comentario, eliminando los caracteres #
iniciales.
El prefijo %prod.
indica que estas propiedades están activas al ejecutarse en el perfil prod
. Para obtener más información sobre los perfiles de configuración, consulte la documentación de Quarkus.
Personalización de la configuración de la base de datos
Agregue las siguientes variables de configuración de base de datos. Reemplace los valores de <DB_SERVER_NAME_VALUE>
y <DB_PASSWORD_VALUE>
por los valores reales de las ${DB_SERVER_NAME}
variables de entorno y ${DB_PASSWORD}
, respectivamente.
# Database configurations
%prod.quarkus.datasource.db-kind=postgresql
%prod.quarkus.datasource.jdbc.url=jdbc:postgresql://<DB_SERVER_NAME_VALUE>.postgres.database.azure.com:5432/todo
%prod.quarkus.datasource.jdbc.driver=org.postgresql.Driver
%prod.quarkus.datasource.username=quarkus@<DB_SERVER_NAME_VALUE>
%prod.quarkus.datasource.password=<DB_PASSWORD_VALUE>
%prod.quarkus.hibernate-orm.database.generation=create
%prod.quarkus.hibernate-orm.sql-load-script=no-file
Por lo general, no se espera que los datos almacenados en la base de datos se quiten y se vuelvan a rellenar con los datos de ejemplo en un entorno de producción. Por eso puede ver que se especifica create
el esquema de para quarkus.hibernate-orm.database.generation
para que la aplicación solo cree el esquema cuando no exista en el inicio inicial. Además, la base de datos no se rellena previamente con ningún dato de ejemplo porque hibernate-orm.sql-load-script
se especifica como no-file
. Esta configuración es diferente de cuando ejecutó la aplicación localmente en modo de desarrollo anteriormente. Los valores predeterminados en modo de desarrollo para quarkus.hibernate-orm.database.generation
y son drop-and-create
y hibernate-orm.sql-load-script
import.sql
respectivamente, lo que significa que la aplicación siempre quita y vuelve a crear el esquema de la base de datos y carga los datos definidos en import.sql. El archivo import.sql es una comodidad de Quarkus. Si el archivo src/main/resources/import.sql existe en el archivo jar de Quarkus y el valor de la hibernate-orm.sql-load-script
propiedad es import.sql
, las instrucciones DML de SQL de este archivo se ejecutan en tiempo de inicio para la aplicación.
Personalización de la configuración de la imagen de contenedor
Como tecnología nativa en la nube, Quarkus admite la generación de imágenes de contenedor OCI compatibles con Docker y Podman. Agregue las siguientes variables de imagen de contenedor. Reemplace los valores de <LOGIN_SERVER_VALUE>
y <USER_NAME_VALUE>
por los valores de los valores reales de las variables de entorno ${LOGIN_SERVER}
y ${USER_NAME}
, respectivamente.
# Container Image Build
%prod.quarkus.container-image.build=true
%prod.quarkus.container-image.registry=<LOGIN_SERVER_VALUE>
%prod.quarkus.container-image.group=<USER_NAME_VALUE>
%prod.quarkus.container-image.name=todo-quarkus-aca
%prod.quarkus.container-image.tag=1.0
Compilación de la imagen de contenedor e inserción en Container Registry
Ahora, use el siguiente comando para compilar la propia aplicación. Este comando usa la extensión Jib para compilar la imagen de contenedor.
quarkus build --no-tests
La salida debe terminar con BUILD SUCCESS
.
Puede comprobar si también se genera la imagen de contenedor mediante la docker
línea de comandos o podman
(CLI). El resultado es similar al ejemplo siguiente:
docker images | grep todo-quarkus-aca
<LOGIN_SERVER_VALUE>/<USER_NAME_VALUE>/todo-quarkus-aca 1.0 0804dfd834fd 2 minutes ago 402MB
Inserte las imágenes de contenedor en Container Registry mediante el comando siguiente:
export TODO_QUARKUS_TAG=$(docker images | grep todo-quarkus-aca | head -n1 | cut -d " " -f1):1.0
echo ${TODO_QUARKUS_TAG}
docker push ${TODO_QUARKUS_TAG}
La salida debería tener un aspecto similar al ejemplo siguiente:
The push refers to repository [<LOGIN_SERVER_VALUE>/<USER_NAME_VALUE>/todo-quarkus-aca]
188a550fce3d: Pushed
4e3afea591e2: Pushed
1db0eba807a6: Pushed
c72d9ccda0b2: Pushed
d7819b8a2d18: Pushed
d0e5cba6b262: Pushed
e0bac91f0f10: Pushed
1.0: digest: sha256:f9ccb476e2388efa0dfdf817625a94f2247674148a69b7e4846793e63c8be994 size: 1789
Ahora que ha insertado la imagen de la aplicación en Container Registry, use el siguiente comando para crear una instancia de Container Apps para ejecutar la aplicación después de extraer la imagen de Container Registry:
az containerapp create \
--resource-group $RESOURCE_GROUP_NAME \
--name $ACA_NAME \
--image $TODO_QUARKUS_TAG \
--environment $ACA_ENV \
--registry-server $LOGIN_SERVER \
--registry-username $USER_NAME \
--registry-password $PASSWORD \
--target-port 8080 \
--ingress 'external'
La salida correcta es un objeto JSON que incluye la propiedad "type": "Microsoft.App/containerApps"
.
Obtenga una dirección URL completa para acceder a la aplicación Todo mediante el siguiente comando:
export QUARKUS_URL=https://$(az containerapp show \
--resource-group $RESOURCE_GROUP_NAME \
--name $ACA_NAME \
--query properties.configuration.ingress.fqdn -o tsv)
echo $QUARKUS_URL
Abra un nuevo explorador web en el valor de ${QUARKUS_URL}
. A continuación, agregue un nuevo elemento de tareas pendientes con el texto Deployed the Todo app to Container Apps
. Seleccione este elemento para marcarlo como completado.
Acceda a la API RESTful (/api
) para obtener todos los elementos de tareas pendientes almacenados en Azure Database for PostgreSQL, como se muestra en el ejemplo siguiente:
curl --verbose -k ${QUARKUS_URL}/api | jq .
La salida debería tener un aspecto similar al ejemplo siguiente:
* Connected to <aca-name>.<random-id>.eastus.azurecontainerapps.io (20.231.235.79) port 443 (#0)
> GET /api HTTP/2
> Host: <aca-name>.<random-id>.eastus.azurecontainerapps.io
> user-agent: curl/7.88.1
> accept: */*
>
< HTTP/2 200
< content-length: 88
< content-type: application/json;charset=UTF-8
<
[
{
"id": 1,
"title": "Deployed the Todo app to Container Apps",
"completed": true,
"order": 1,
"url": null
}
]
Comprobación de que la base de datos se ha actualizado mediante Azure Cloud Shell
Abra Azure Cloud Shell en Azure Portal; para ello, seleccione el icono de Cloud Shell ( ) situado junto al cuadro de búsqueda.
Ejecute el siguiente comando localmente y pegue el resultado en Azure Cloud Shell:
echo psql --host=${DB_SERVER_NAME}.postgres.database.azure.com --port=5432 --username=quarkus@${DB_SERVER_NAME} --dbname=todo
Cuando se le solicite la contraseña, use el valor que empleó al crear la base de datos.
Use la consulta siguiente para obtener todos los elementos de tareas pendientes:
select * from todo;
La salida debe ser similar al ejemplo siguiente y debe incluir los mismos elementos en la GUI de la aplicación de tareas pendientes mostrada anteriormente:
Escriba \q para salir del programa psql
y vuelva al Cloud Shell.
Limpieza de recursos
Para evitar los cargos de Azure, se recomienda limpiar los recursos que no sean necesarios. Cuando el clúster ya no se necesite, puede usar el comando az group delete para quitar el grupo de recursos, el servicio de contenedor, el registro de contenedor y todos los recursos relacionados.
git reset --hard
docker rmi ${TODO_QUARKUS_TAG}
az group delete --name $RESOURCE_GROUP_NAME --yes --no-wait
También puede usar docker rmi
para eliminar las postgres
imágenes de contenedor y testcontainers
generadas por el modo de desarrollo de Quarkus.
Pasos siguientes
Comentarios
https://aka.ms/ContentUserFeedback.
Próximamente: A lo largo de 2024 iremos eliminando gradualmente GitHub Issues como mecanismo de comentarios sobre el contenido y lo sustituiremos por un nuevo sistema de comentarios. Para más información, vea:Enviar y ver comentarios de