Share via


Azure Container Apps に Quarkus を使用して Java アプリケーションをデプロイする

この記事では、簡単な CRUD アプリケーションを使用して、Microsoft Azure Container Apps に Red Hat Quarkus をすばやくデプロイする方法について説明します。 このアプリケーションは、JavaScript フロントエンドと REST エンドポイントを備えた "To Do リスト" です。 Azure Database for PostgreSQL は、アプリの永続化レイヤーを提供します。 この記事では、アプリをローカルでテストし、Container Apps にデプロイする方法について説明します。

前提条件

  • Azure サブスクリプションをお持ちでない場合は、開始する前に無料アカウントを作成してください。
  • Azure Cloud Shell には、これらの前提条件がすべてプレインストールされています。 詳細については、「Azure Cloud Shell のクイックスタート」を参照してください。
  • (Azure Cloud Shell を使用するのではなく) このガイドのコマンドをローカルで実行している場合は、次の手順を実行します。
    • Unix のようなオペレーティング システム (Ubuntu、macOS、または Linux 用 Windows サブシステムなど) がインストールされているローカル マシンを準備します。
    • Java SE 実装バージョン 17 以降 (たとえば、 OpenJDK の Microsoft ビルド) をインストールします。
    • Maven 3.5.0 以上をインストールします。
    • お使いの OS 用の Docker または Podman をインストールします。
    • jq をインストールします。
    • cURL をインストールします。
    • Quarkus CLI 3.4.1 以降をインストールします。
  • Unix に似た環境用の Azure CLI。 この記事では、Azure CLI の Bash バリアントのみが必要です。
    • Azure CLI をインストールし、az login コマンドを使用して対話形式でサインインし、コードで を使用DefaultAzureCredentialする前に Azure にログインします。
      az login
      
    • この記事では、バージョン 2.31.0 以上の Azure CLI が必要です。 Azure Cloud Shell を使用している場合は、最新バージョンが既にインストールされています。

アプリ プロジェクトを作成する

次のコマンドを使って、この記事用のサンプル Java プロジェクトをクローンします。 サンプルは GitHub にあります。

git clone https://github.com/Azure-Samples/quarkus-azure
cd quarkus-azure
git checkout 2023-09-13
cd aca-quarkus

HEAD がデタッチされた状態であることを示すメッセージが表示された場合、このメッセージは無視しても問題ありません。 この記事ではコミットを必要としないため、HEAD がデタッチされた状態が適切です。

Quarkus アプリをローカルでテストする

このセクションの手順では、アプリをローカルで実行する方法を示します。

Quarkus は、開発モードおよびテスト モードでの未構成のサービスの自動プロビジョニングをサポートしています。 Quarkus は、この機能を開発サービスと呼びます。 データベース サービスへの接続などの Quarkus 機能が含まれているとします。 アプリをテストしたいと考えていますが、実際のデータベースへの接続がまだ完全に構成されていません。 Quarkus は、関連するサービスのスタブ バージョンを自動的に開始し、アプリケーションをそれに接続します。 詳細については、Quarkus ドキュメントの「Dev Services の概要」を参照してください。

コンテナー環境 (Docker または Podman) が実行されていることを確認し、次のコマンドを使用して Quarkus 開発モードに入ります。

quarkus dev

quarkus dev の代わりに、 mvn quarkus:dev を使用すると、Maven で同じことを実現できます。

Quarkus 開発モードの使用状況のテレメトリを送信するかどうかを確認するメッセージが表示される場合があります。 その場合は、好きなように答えてください。

Quarkus 開発モードでは、バックグラウンド コンパイルによるライブ リロードが有効になります。 アプリのソース コードの一部を変更してブラウザーを更新すると、変更内容を確認できます。 コンパイルまたはデプロイに問題がある場合は、エラー ページが表示されます。 Quarkus 開発モードは、ポート 5005 でデバッガーをリッスンします。 デバッガーが接続されるのを待ってから実行する場合は、コマンド ラインで -Dsuspend を渡します。 デバッガーがまったく不要な場合は、-Ddebug=false を使用できます。

出力は次の例のようになります。

__  ____  __  _____   ___  __ ____  ______
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
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>

Quarkus 開発モードが実行されているターミナルで w キーを押します。 w キーを押すとデフォルトの Web ブラウザーが開き、Todo アプリケーションが表示されます。 http://localhost:8080 にあるアプリケーション GUI に直接アクセスすることもできます。

Todo サンプル アプリのスクリーンショット。

Todo リストで Todo 項目をいくつか選択してみてください。 UI は取り消し線のテキスト スタイルで選択を示します。 次のスクリーンショットに示すように、「Todo アプリの確認」と入力して Enter キー を押して、新しい Todo 項目を Todo リストに追加することもできます。

新しい項目が追加された Todo サンプル アプリのスクリーンショット。

RESTful API (/api) にアクセスして、ローカル PostgreSQL データベースに保存されているすべての ToDo 項目を取得します。

curl --verbose http://localhost:8080/api | jq .

出力は次の例のようになります。

* 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
  }
]

q キーを押して Quarkus 開発モードを終了します。

Azure リソースを作成して Quarkus アプリを実行する

このセクションの手順では、次の Azure リソースを作成して Quarkus サンプル アプリを実行する方法を示します。

  • Microsoft Azure Database for PostgreSQL
  • Microsoft Azure Container Registry
  • コンテナー アプリ

これらのリソースの一部は、Azure サブスクリプションのスコープ内で一意の名前を持つ必要があります。 この一意性を確保するために、 イニシャル、シーケンス、日付、サフィックス パターンを使用できます。 このパターンを適用するには、イニシャル、シーケンス番号、今日の日付、およびリソース固有のサフィックス (たとえば、"リソース グループ" の場合は rg) を一覧表示してリソースに名前を付けます。 次のコマンドを使用して、後で使用するいくつかの環境変数を定義します。

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

Azure Database for PostgreSQL の作成

Azure Database for PostgreSQL は、高可用性の PostgreSQL データベースを Azure クラウドで実行、管理、スケールできるマネージド サービスです。 このセクションでは、単一の Azure Database for PostgreSQL サーバーを作成し、それに接続する方法を示す別のクイックスタートを紹介します。 ただし、クイックスタートの手順に従う場合は、次の表の設定を使用して、サンプル Quarkus アプリのデータベース デプロイをカスタマイズする必要があります。 Azure portal のフィールドに入力するときに、環境変数を実際の値に置き換えます。

設定 説明
リソース グループ ${RESOURCE_GROUP_NAME} [新規作成] を選択します。 デプロイでは、この新しいリソース グループが作成されます。
サーバー名 ${DB_SERVER_NAME} この値は、データベース サーバーのホスト名の一部を形成します。
場所 ${LOCATION} ドロップダウン リストから場所を選択します。 場所を記録しておきます。 作成する他の Azure リソースにもこれと同じ場所を使用する必要があります。
管理者ユーザー名 Quarkus サンプル コードでは、この値を前提としています。
パスワード ${DB_PASSWORD} パスワードは 8 文字以上、最大 128 文字にする必要があります。 パスワードには、英大文字、英小文字、数字 (0 ~ 9)、英数字以外の文字 (!、$、#、% など) のうち、3 つのカテゴリの文字が含まれている必要があります。 パスワードにサインイン名の全部または一部を含めることはできません。 サインイン名の一部は、3 つ以上の連続する英数字として定義されます。

これらの値の置換を念頭に置き、「クイック スタート: Azure portal を使用して Azure Database for PostgreSQL サーバーを作成する」の手順を "ファイアウォール ルールの構成" セクションまで実行します。 次に、"ファイアウォール ルールの構成" セクションで、[Azure サービスへのアクセスを許可する] で必ず [はい] を選択し、[保存] を選択します。 これを怠ると、Quarkus アプリはデータベースにアクセスできなくなり、起動できなくなります。

Azure サービスへのアクセスを許可する手順を含む、クイックスタートの "ファイアウォール ルールの構成" セクションの手順を完了したら、この記事に戻ってください。

Azure Database for PostgreSQLで Todo データベースを作成する

先ほど作成した PostgreSQL サーバーは空です。 Quarkus アプリケーションで使用できるデータベースはありません。 次のコマンドを使用し、todo という名前の新しいデータベースを作成します。

az postgres db create \
    --resource-group ${RESOURCE_GROUP_NAME} \
    --name todo \
    --server-name ${DB_SERVER_NAME}

サンプル コードではデータベース名が前提であるため、データベースの名前として を使用 todo する必要があります。

コマンドが成功した場合、出力は次の例のようになります。

{
  "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"
}

Microsoft Azure Container Registry インスタンスを作成する

Quarkus はクラウド ネイティブ テクノロジであるため、Container Apps で実行されるコンテナーを作成するためのサポートが組み込まれています。 Container Apps は、実行するコンテナー イメージを見つけるコンテナー レジストリを持つことに完全に依存します。 Container Apps には、Azure Container Registryのサポートが組み込まれています。

az acr create コマンドを使用して、Container Registry インスタンスを作成します。 次の例では、環境変数 ${REGISTRY_NAME}の値を使用して、 という名前の n 個の Container Registry インスタンスを作成します。

az acr create \
    --resource-group $RESOURCE_GROUP_NAME \
    --location ${LOCATION} \
    --name $REGISTRY_NAME \
    --sku Basic \
    --admin-enabled

しばらくすると、次の行を含む JSON 出力が表示されます。

  "provisioningState": "Succeeded",
  "publicNetworkAccess": "Enabled",
  "resourceGroup": "<YOUR_RESOURCE_GROUP>",

Docker を Container Registry インスタンスに接続する

Container Registry インスタンスにサインインします。 サインインすると、イメージをプッシュできます。 次のコマンドを使用して、接続を確認します。

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

Docker の代わりに Podman を使用している場合は、 コマンドに必要な変更を加えます。

Container Registry インスタンスに正常にサインインした場合は、コマンド出力の最後にが表示 Login Succeeded されます。

環境の作成

Azure Container Apps 環境では、コンテナー アプリのグループを囲むセキュリティ保護された境界が作成されます。 同じ環境にデプロイされた Container Apps は、同じ仮想ネットワークにデプロイされ、同じ Log Analytics ワークスペースにログを書き込みます。 次の例に示すように、 az containerapp env create コマンドを使用して環境を作成します。

az containerapp env create \
    --resource-group $RESOURCE_GROUP_NAME \
    --location $LOCATION \
    --name $ACA_ENV

拡張機能のインストールを求められた場合は、Y と回答 します

クラウド ネイティブ構成をカスタマイズする

クラウド ネイティブ テクノロジとして、Quarkus はコンテナー イメージを自動的に生成する機能を提供します。 詳細については、「 コンテナー イメージ」を参照してください。 その後、開発者は、ターゲットのコンテナー化されたプラットフォーム (Azure Container Apps など) にアプリケーション イメージをデプロイできます。

コンテナー イメージを生成するには、次のコマンドを使用して、ローカル ターミナルに container-image-jib 拡張機能を追加します。

quarkus ext add container-image-jib

Quarkus は POM を変更して、拡張機能が に含まれるようにします <dependencies>。 と呼ばれる JBangものをインストールするように求められた場合は、「 はい」 と答え、インストールを許可します。

出力は次の例のようになります。

[SUCCESS] ✅  Extension io.quarkus:quarkus-container-image-jib has been installed

拡張機能が追加されたことを確認するには、git diff を実行して出力を調べます。

Quarkus はクラウド ネイティブ テクノロジーとして、構成プロファイルの概念をサポートしています。 Quarkus には、次の 3 つの組み込みプロファイルがあります。

  • dev - 開発モードの場合にアクティブ化されます。
  • test - テストの実行時にアクティブ化されます。
  • prod - 開発モードまたはテスト モードで実行されていない場合の既定のプロファイル。

Quarkus は、必要に応じて、任意の数の名前付きプロファイルをサポートします。

このセクションの残りの手順では、src/main/resources/application.properties ファイルのコメントを解除して値をカスタマイズする方法を説明します。 先頭の # を削除して、# %prod. で始まるすべての行のコメントが解除されていることを確認します。

%prod. プレフィックスは、prod プロファイルでの実行時にこれらのプロパティがアクティブであることを示します。 構成プロファイルの詳細については、Quarkus のドキュメントを参照してください。

データベース構成をカスタマイズする

次のデータベース構成変数を追加します。 と <DB_PASSWORD_VALUE><DB_SERVER_NAME_VALUE>値をそれぞれ、 および ${DB_PASSWORD} 環境変数の実際の${DB_SERVER_NAME}値に置き換えます。

# 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

一般に、データベースに保持されているデータが削除され、運用環境のサンプル データが再入力されるとは思われません。 そのため、 のスキーマ quarkus.hibernate-orm.database.generation が として create 指定されていることがわかります。そのため、最初の起動時にスキーマが存在しない場合にのみ、アプリによってスキーマが作成されます。 また、 は としてno-file指定されているためhibernate-orm.sql-load-script、データベースにはサンプル データが事前に設定されていません。 この設定は、以前に開発モードでアプリをローカルで実行した場合とは異なります。 と の開発モードquarkus.hibernate-orm.database.generationの既定値はそれぞれ drop-and-createimport.sql です。つまり、アプリは常にデータベース スキーマを削除して再作成し、import.sql で定義されているデータを読み込みます。hibernate-orm.sql-load-script import.sql ファイルは、Quarkus の便利な機能です。 src/メイン/resources/import.sql ファイルが Quarkus jar に存在し、 プロパティの値が の場合、import.sqlこのファイル内の hibernate-orm.sql-load-script SQL DML ステートメントはアプリの起動時に実行されます。

コンテナー イメージの構成をカスタマイズする

Quarkus は、クラウド ネイティブ テクノロジーとして、Docker および Podman と互換性のある OCI コンテナー イメージの生成をサポートしています。 次のコンテナー イメージ変数を追加します。 <LOGIN_SERVER_VALUE><USER_NAME_VALUE> の値を、それぞれ ${LOGIN_SERVER}${USER_NAME} 環境変数の実際の値に置き換えます。

# 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

コンテナー イメージをビルドし、コンテナー レジストリにプッシュする

次に、次のコマンドを使用してアプリケーション自体をビルドします。 このコマンドでは、Jib 拡張機能を使用してコンテナー イメージをビルドします。

quarkus build --no-tests

出力は BUILD SUCCESS で終わる必要があります。

コンテナー イメージが生成されるかどうかを確認するには、 または podman コマンド ライン (CLI) を使用dockerします。 出力は次の例のようになります。

docker images | grep todo-quarkus-aca
<LOGIN_SERVER_VALUE>/<USER_NAME_VALUE>/todo-quarkus-aca   1.0       0804dfd834fd   2 minutes ago   402MB

次のコマンドを使用して、コンテナー イメージを Container Registry にプッシュします。

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}

出力は次の例のようになるはずです。

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

アプリ イメージを Container Registry にプッシュしたので、次のコマンドを使用して Container Apps インスタンスを作成し、コンテナー レジストリからイメージをプルした後でアプリを実行します。

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'

正常な出力は、 プロパティを含む JSON オブジェクトです "type": "Microsoft.App/containerApps"

次のコマンドを使用して、Todo アプリケーションにアクセスするための完全修飾 URL を取得します。

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

新しい Web ブラウザーを開いて値を ${QUARKUS_URL} に設定します。 次に、テキスト Deployed the Todo app to Container Apps を含む新しい Todo 項目を追加します。 この項目を選択して、完了としてマークします。

Container Apps で実行されている Todo サンプル アプリのスクリーンショット。

次の例に示すように、RESTful API (/api) にアクセスして、Azure Database for PostgreSQLに格納されているすべての todo 項目を取得します。

curl --verbose -k ${QUARKUS_URL}/api | jq .

出力は次の例のようになります。

* 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
  }
]

Azure Cloud Shellを使用してデータベースが更新されたことを確認します

検索ボックスの横にあるCloud Shell アイコン ( ) を選択して、Azure portalで Azure Cloud Shellを開きます。

次のコマンドをローカルで実行し、結果を Azure Cloud Shell に貼り付けます。

echo psql --host=${DB_SERVER_NAME}.postgres.database.azure.com --port=5432 --username=quarkus@${DB_SERVER_NAME} --dbname=todo

パスワードを求められたら、データベースの作成時に使用した値を使用します。

次のクエリを使用して、すべての ToDo 項目を取得します。

select * from todo;

出力は次の例のようになり、前に示した Todo アプリ GUI に同じ項目が含まれているはずです。

ASCII テーブルとして出力されたクエリのスクリーンショット。

\q」と入力して、psql プログラムを終了し、Cloud Shell に戻ります。

リソースをクリーンアップする

Azure の課金を回避するには、不要なリソースをクリーンアップする必要があります。 クラスターが必要なくなったら、az group delete コマンドを使って、リソース グループ、コンテナー サービス、コンテナー レジストリ、およびすべての関連リソースを削除してください。

git reset --hard
docker rmi ${TODO_QUARKUS_TAG}
az group delete --name $RESOURCE_GROUP_NAME --yes --no-wait

を使用docker rmiして、Quarkus 開発モードによって生成された および コンテナー イメージを削除postgrestestcontainersすることもできます。

次の手順