この記事は、Azure Container Appsを
このチュートリアルでは、次の操作を行います。
- クラウドでコンテナー イメージを構築して、Python サンプル Web アプリ (Django または Flask) をコンテナー化します。
- コンテナー イメージを Azure Container Apps にデプロイします。
- サンプル アプリがデータを格納する Azure Database for PostgreSQL - フレキシブル サーバー インスタンスにコンテナー アプリが接続できるようにする環境変数を定義します。
次の図は、このチュートリアルのタスクであるコンテナー イメージのビルドとデプロイを示しています。
前提 条件
Azure サブスクリプションをお持ちでない場合は、開始する前に 無料アカウント を作成してください。
Azure CLI コマンドは、Azure Cloud Shell
ローカルで実行している場合は、次の手順に従ってサインインし、このチュートリアルに必要なモジュールをインストールします。
必要に応じて、Azure にサインインして認証します。
az login
最新バージョンの Azure CLI を実行していることを確認します。
az upgrade
az extension add コマンドを使用して、containerapp と rdbms-connect の Azure CLI 拡張機能をインストールまたはアップグレードします。
az extension add --name containerapp --upgrade az extension add --name rdbms-connect --upgrade
注
システムにインストールされている拡張機能を一覧表示するには、az extension list コマンドを使用します。 例えば:
az extension list --query [].name --output tsv
サンプル アプリを入手する
サンプル コードをフォークして開発者環境に複製します。
サンプル アプリの GitHub リポジトリ (Django または Flask) に移動し、[Fork] を選択します。
手順に従って、リポジトリを GitHub アカウントにフォークします。 フォークや GitHub アカウントを使用せずに、コード リポジトリをローカル コンピューターに直接ダウンロードすることもできます。 ただし、ダウンロード方法を使用する場合は、このシリーズの次のチュートリアルで継続的インテグレーションと継続的デリバリー (CI/CD) を設定することはできません。
コンソールのコマンド プロンプトで、 git clone コマンドを使用して、フォークされたリポジトリを python-container フォルダーに複製します。
# Django git clone https://github.com/<github-username>/msdocs-python-django-azure-container-apps.git python-container # Flask # git clone https://github.com/<github-username>/msdocs-python-flask-azure-container-apps.git python-container
ディレクトリを変更します。
cd python-container
Web アプリ コードからコンテナー イメージをビルドする
これらの手順を実行すると、サンプル コードからビルドされた Docker コンテナー イメージを含む Azure Container Registry インスタンスが作成されます。
Windows コンピューター上の Git Bash シェルでコマンドを実行している場合は、続行する前に次のコマンドを入力します。
#!/bin/bash export MSYS_NO_PATHCONV=1
az group create コマンドを使用してリソース グループを作成します。
#!/bin/bash RESOURCE_GROUP_NAME=<resource-group-name> LOCATION=<___location> az group create \ --name $RESOURCE_GROUP_NAME \ --___location $LOCATION
az acr create コマンドを使用して、コンテナー レジストリを作成します。
#!/bin/bash REGISTRY_NAME=<registry-name> #The name that you use for *\<registry-name>* must be unique within Azure, and it must contain 5 to 50 alphanumeric characters. az acr create \ --resource-group $RESOURCE_GROUP_NAME \ --name $REGISTRY_NAME \ --sku Basic \ --admin-enabled true
az acr login コマンドを使用してレジストリにサインインします。
az acr login --name $REGISTRY_NAME
このコマンドは、名前に "azurecr.io" を追加して、完全修飾レジストリ名を作成します。 サインインに成功すると、"ログインに成功しました" というメッセージが表示されます。 レジストリを作成したサブスクリプションとは異なるサブスクリプションからレジストリにアクセスする場合は、
--suffix
スイッチを使用します。サインインに失敗した場合は、Docker デーモンがシステムで実行されていることを確認します。
az acr build コマンドを使用してイメージをビルドします。
#!/bin/bash az acr build \ --registry $REGISTRY_NAME \ --resource-group $RESOURCE_GROUP_NAME \ --image pythoncontainer:latest .
次の考慮事項が適用されます。
コマンドの末尾にあるドット (
.
) は、ビルドするソース コードの場所を示します。 サンプル アプリのルート ディレクトリでこのコマンドを実行していない場合は、コードへのパスを指定します。Azure Cloud Shell でコマンドを実行している場合は、
git clone
を使用して、最初にリポジトリを Cloud Shell 環境にプルします。 次に、プロジェクトのルートにディレクトリを変更して、ドット (.
) が正しく解釈されるようにします。-t
(--image
と同じ) オプションを指定しなかった場合、このコマンドでは、ローカル コンテキスト ビルドがレジストリにプッシュされずにキューに入れられます。 プッシュなしのビルドは、イメージがビルドされるか確認する場合に便利です。
az acr repository list コマンドを使用して、コンテナー イメージが作成されたことを確認します。
az acr repository list --name $REGISTRY_NAME
注
このセクションの手順では、Basic サービス レベルでコンテナー レジストリを作成します。 このレベルはコスト最適化されており、機能セットとスループットは開発者シナリオを対象としており、このチュートリアルの要件に適しています。 運用環境のシナリオでは、Standard または Premium のいずれかのサービス レベルを使用する可能性が最も高くなります。 これらのレベルでは、強化されたレベルのストレージとスループットが提供されます。
詳細については、Azure Container Registry サービス レベル
PostgreSQL フレキシブル サーバー インスタンスを作成する
サンプル アプリ (Django または Flask) は、PostgreSQL データベースにレストランのレビュー データを格納します。 これらの手順では、データベースを含むサーバーを作成します。
az postgres flexible-server create コマンドを使用して、Azure に PostgreSQL サーバーを作成します。 このコマンドが完了する前に数分間実行することは珍しくありません。
#!/bin/bash ADMIN_USERNAME=demoadmin ADMIN_PASSWORD=<admin-password> # Use a strong password that meets the requirements for PostgreSQL. POSTGRES_SERVER_NAME=<postgres-server-name> az postgres flexible-server create \ --resource-group $RESOURCE_GROUP_NAME \ --name $POSTGRES_SERVER_NAME \ --___location $LOCATION \ --admin-user $ADMIN_USERNAME \ --admin-password $ADMIN_PASSWORD \ --version 16 \ --tier Burstable \ --sku-name Standard_B1ms \ --public-access 0.0.0.0 \ --microsoft-entra-auth Enabled \ --storage-size 32 \ --backup-retention 7 \ --high-availability Disabled \ --yes
次の値を使用します。
<postgres-server-name>: PostgreSQL データベース サーバー名。 この名前は、すべての Azure で一意である必要があります。 サーバー エンドポイントが
https://<postgres-server-name>.postgres.database.azure.com
。 使用できる文字は、A
からZ
、0
から9
、およびハイフン (-
) です。<場所>: Web アプリに使用したのと同じ場所を使用します。 <場所> は、コマンド
Name
の出力からの Azure の場所az account list-locations -o table
値の 1 つです。<admin-username>: 管理者アカウントのユーザー名。
azure_superuser
、admin
、administrator
、root
、guest
、またはpublic
することはできません。 このチュートリアルでは、demoadmin
を使用します。<admin-password>: 管理者ユーザーのパスワード。 これには、次のうちの 3 つのカテゴリの、8 から 128 文字が含まれている必要があります。英大文字、英小文字、数字、英数字以外の文字のうち、3 つのカテゴリの文字が含まれている必要があります。
重要
ユーザー名またはパスワードを作成するときは、ドル記号 ($) 文字を使用しないでください。 後でこれらの値を使用して環境変数を作成すると、その文字は、Python アプリの実行に使用する Linux コンテナー内で特別な意味を持ちます。
--version
:16
を使用します。 サーバーに使用する PostgreSQL のバージョンを指定します。--tier
:Burstable
を使用します。 サーバーの価格レベルを指定します。 Burstable レベルは、完全な CPU を継続的に必要としないワークロードの低コストのオプションであり、このチュートリアルの要件に適しています。--sku-name
: 価格レベルとコンピューティング構成の名前。たとえば、Standard_B1ms
します。 詳しくは、「Azure Database for PostgreSQL の価格」をご覧ください。 使用可能なレベルを一覧表示するには、az postgres flexible-server list-skus --___location <___location>
を使用します。--public-access
:0.0.0.0
を使用します。 これにより、Container Apps などの任意の Azure サービスからサーバーへのパブリック アクセスが許可されます。--microsoft-entra-auth
:Enabled
を使用します。 サーバーで Microsoft Entra 認証を有効にします。--storage-size
:32
を使用します。 サーバーのストレージ サイズをギガバイト (GB) 単位で指定します。 最小値は 32 GB です。--backup-retention
:7
を使用します。 サーバーのバックアップを保持する日数を指定します。 最小値は 7 日です。--high-availability
:Disabled
を使用します。 サーバーの高可用性が無効になります。 このチュートリアルでは、高可用性は必要ありません。--yes
: PostgreSQL サーバーの使用条件に同意します。
注
ツールを使用してローカル ワークステーションから PostgreSQL サーバーを操作する場合は、az postgres flexible-server firewall-rule create コマンド
使用して、ワークステーションの IP アドレスのファイアウォール規則を追加する必要があります。 ユーザー アカウントのオブジェクト ID を取得するには、az ad signed-in-user show コマンドを使用します。 この ID は、次のコマンドで使用します。
#!/bin/bash CALLER_OBJECT_ID=$(az ad signed-in-user show --query id -o tsv) CALLER_DISPLAY_NAME=$(az ad signed-in-user show --query userPrincipalName -o tsv)
az postgres flexible-server ad-admin create コマンドを使用して、PostgreSQL サーバーに Microsoft Entra 管理者としてユーザー アカウントを追加します。
#!/bin/bash az postgres flexible-server microsoft-entra-admin create \ --server-name "$POSTGRES_SERVER_NAME" \ --resource-group "$RESOURCE_GROUP_NAME" \ --display-name "$CALLER_DISPLAY_NAME" \ --object-id "$CALLER_OBJECT_ID" \ --type User
Web アプリが PostgeSQL フレキシブル サーバーにアクセスできるようにする規則を追加するには、az postgres flexible-server firewall-rule create コマンドを使用します。 次のコマンドでは、パブリック IP アドレスを使用して、開発ワークステーションからの接続を受け入れるようにサーバーのファイアウォールを構成します。
MY_IP=$(curl -s ifconfig.me) az postgres flexible-server firewall-rule create \ --name "$POSTGRES_SERVER_NAME" \ --resource-group "$RESOURCE_GROUP_NAME" \ --rule-name allow-my-ip \ --start-ip-address "$MY_IP" \ --end-ip-address "$MY_IP" ```
注
このセクションの手順では、バースト可能価格レベルで単一の仮想コアと制限付きメモリを備えた PostgreSQL サーバーを作成します。 Burstable レベルは、完全な CPU を継続的に必要としないワークロードの低コストのオプションであり、このチュートリアルの要件に適しています。 運用環境のワークロードの場合は、General Purpose または Memory Optimized のいずれかの価格レベルにアップグレードできます。 これらのレベルでは、パフォーマンスは向上しますが、コストは増加します。
詳細については、Azure Database for PostgreSQL - フレキシブル サーバーのコンピューティング オプションの
サーバー上にデータベースを作成する
この時点で、PostgreSQL サーバーがあります。 このセクションでは、サーバー上にデータベースを作成します。
az postgres flexible-server db create コマンドを使用して、restaurants_reviewsという名前のデータベースを作成します。
#!/bin/bash
DATABASE_NAME=restaurants_reviews
az postgres flexible-server db create \
--resource-group $RESOURCE_GROUP_NAME \
--server-name $POSTGRES_SERVER_NAME \
--database-name $DATABASE_NAME
az postgres flexible-server connect コマンドを使用してデータベースに接続し、psql コマンドを操作することもできます。 psql を使用する場合、シェルにはすべての依存関係が含まれているため、Azure Cloud Shell
また、Azure Database for PostgreSQL フレキシブル サーバーに接続し、
ユーザー割り当てマネージド ID を作成する
Azure で実行されているときにコンテナー アプリの ID として使用するユーザー割り当てマネージド ID を作成します。
注
ユーザー割り当てマネージド ID を作成するには、アカウントに マネージド ID 共同作成者 ロールの割り当てが必要です。
az identity create コマンドを使用して、ユーザー割り当てマネージド ID を作成します。
UA_MANAGED_IDENTITY_NAME=<managed-identity-name> # Use a unique name for the managed identity, such as-"my-ua-managed-id".
az identity create \
--name $UA_MANAGED_IDENTITY_NAME
--resource-group $RESOURCE_GROUP_NAME
PostgreSQL データベースでマネージド ID を構成する
PostgreSQL サーバーのロールとしてマネージド ID を構成し、restaurants_reviews データベースに必要なアクセス許可を付与します。 Azure CLI または psql のどちらを使用している場合でも、サーバー インスタンスで Microsoft Entra 管理者として構成されているユーザーを使用して Azure PostgreSQL サーバーに接続する必要があります。 サーバーでマネージド ID やその他の Microsoft 管理者ロールを構成できるのは、PostgreSQL 管理者として構成された Microsoft Entra アカウントのみです。
az account get-access-token コマンドを使用して、Azure アカウントのアクセス トークンを取得します。 アクセス トークンは、次の手順で使用します。
#!/bin/bash MY_ACCESS_TOKEN=$(az account get-access-token --resource-type oss-rdbms --output tsv --query accessToken) echo $MY_ACCESS_TOKEN
PostgreSQL サーバーにユーザー割り当てマネージド ID をデータベース ロールとして追加するには、az postgres flexible-server execute コマンドを使用します。
#!/bin/bash az postgres flexible-server execute \ --name "$POSTGRES_SERVER_NAME" \ --admin-user "$CALLER_DISPLAY_NAME" \ --admin-password "$ACCESS_TOKEN" \ --database-name postgres \ --querytext "SELECT * FROM pgaadauth_create_principal('$UA_MANAGED_IDENTITY_NAME', false, false);"
注
ローカル ワークステーションで
az postgres flexible-server execute
コマンドを実行している場合は、ワークステーションの IP アドレスのファイアウォール規則を追加したことを確認します。 az postgres flexible-server firewall-rule create コマンド使用して、規則を追加できます。 次の手順では、コマンドにも同じ要件が存在します。 次の az postgres flexible-server execute コマンドを使用して、restaurants_reviews データベースに対する必要なアクセス許可をユーザー割り当てマネージド ID に付与します。
#!/bin/bash SQL_GRANTS=$(cat <<EOF GRANT CONNECT ON DATABASE $DATABASE_NAME TO "$UA_MANAGED_IDENTITY_NAME"; GRANT USAGE, CREATE ON SCHEMA public TO "$UA_MANAGED_IDENTITY_NAME"; GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO "$UA_MANAGED_IDENTITY_NAME"; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO "$UA_MANAGED_IDENTITY_NAME"; EOF ) az postgres flexible-server execute \ --name "$POSTGRES_SERVER_NAME" \ --admin-user "$CALLER_DISPLAY_NAME" \ --admin-password "$MY_ACCESS_TOKEN" \ --database-name "$DATABASE_NAME" \ --querytext "$SQL_GRANTS"
この Azure CLI コマンドは、サーバー上の restaurants_reviews データベースに接続し、次の SQL コマンドを発行します。
GRANT CONNECT ON DATABASE restaurants_reviews TO "my-ua-managed-id"; GRANT USAGE ON SCHEMA public TO "my-ua-managed-id"; GRANT CREATE ON SCHEMA public TO "my-ua-managed-id"; GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO "my-ua-managed-id"; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO "my-ua-managed-id";
Container Apps に Web アプリをデプロイする
Azure Container Apps 環境 は、セキュリティで保護された境界として機能し、そこにコンテナー アプリがデプロイされます。 次の手順では、環境内に環境とコンテナーを作成します。 次に、Web サイトが外部に表示されるようにコンテナーを構成します。
これらの手順には、azure Container Apps 拡張機能 containerappが必要です。
az containerapp env create コマンドを使用して Container Apps 環境を作成します。
#!/bin/bash APP_ENV_NAME=<app-env-name> # Use a unique name for the environment, such as "python-container-env". az containerapp env create \ --name python-container-env \ --resource-group $RESOURCE_GROUP_NAME \ --___location $LOCATION
az acr credential show コマンドを使用して、Azure Container Registry インスタンスのサインイン資格情報を取得します。
#!/bin/bash REGISTRY_CREDS=$(az acr credential show -n "$REGISTRY_NAME" --query "[username,passwords[0].value]" -o tsv) REGISTRY_USERNAME=$(echo "$REGISTRY_CREDS" | head -n1) REGISTRY_PASSWORD=$(echo "$REGISTRY_CREDS" | tail -n1)
手順 5 でコンテナー アプリを作成するときに、コマンドの出力から返されたユーザー名とパスワードの 1 つを使用します。
az identity show コマンドを使用して、ユーザー割り当てマネージド ID のクライアント ID とリソース ID を取得します。
UA_CLIENT_ID=$(az identity show \ --name "$UA_MANAGED_IDENTITY_NAME" \ --resource-group "$RESOURCE_GROUP" \ --query clientId -o tsv) UA_RESOURCE_ID=$(az identity show \ --name "$UA_MANAGED_IDENTITY_NAME" \ --resource-group "$RESOURCE_GROUP" \ --query id -o tsv)
手順 5 でコンテナー アプリを作成するときに、コマンドの出力のクライアント ID (GUID) とリソース ID の値を使用します。 リソース ID の形式は次のとおりです:
/subscriptions/<subscription-id>/resourcegroups/pythoncontainer-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/my-ua-managed-id
。次のコマンドを実行して、秘密鍵の値を生成します。
AZURE_SECRET_KEY=$(python -c 'import secrets; print(secrets.token_hex())')
手順 5 でコンテナー アプリを作成するときに、秘密鍵の値を使用して環境変数を設定します。
注
この手順で示すコマンドは、Bash シェル用です。 環境によっては、
python3
を使用して Python を呼び出す必要がある場合があります。 Windows では、コマンドを-c
パラメーターで単一引用符ではなく二重引用符で囲む必要があります。 また、環境によっては、py
またはpy -3
を使用して Python を呼び出す必要がある場合もあります。az containerapp create コマンドを使用して、環境内にコンテナー アプリを作成します。
az containerapp create \ --name "$CONTAINER_APP_NAME" \ --resource-group "$RESOURCE_GROUP" \ --environment "$APP_ENV" \ --image "$REGISTRY_NAME.azurecr.io/$IMAGE_NAME" \ --target-port "$TARGET_PORT" \ --ingress external \ --registry-server "$REGISTRY_NAME.azurecr.io" \ --registry-username "$REGISTRY_USERNAME" \ --registry-password "$REGISTRY_PASSWORD" \ --user-assigned "$UA_RESOURCE_ID" \ --env-vars \ DBHOST="$POSTGRES_SERVER_NAME" \ DBNAME="$DATABASE_NAME" \ DBUSER="$UA_MANAGED_IDENTITY_NAME" \ RUNNING_IN_PRODUCTION=1 \ AZURE_CLIENT_ID="$UA_CLIENT_ID" \ AZURE_SECRET_KEY="$AZURE_SECRET_KEY" ```
Django の場合のみ、データベース スキーマを移行して作成します。 (Flask サンプル アプリでは自動的に実行されるため、この手順をスキップできます)。
az containerapp exec コマンドを使用して接続します。
az containerapp exec \ --name $CONTAINER_APP_NAME \ --resource-group $RESOURCE_GROUP_NAME
次に、シェルのコマンド プロンプトで、「
python manage.py migrate
」と入力します。コンテナーのリビジョンについては、移行する必要はありません。
Web サイトをテストします。
入力した
az containerapp create
コマンドは、アプリの参照に使用できるアプリケーション URL を出力します。 URL はazurecontainerapps.io
で終わります。 ブラウザーで URL に移動します。 または、az containerapp browse コマンドを使用することもできます。
レストランと 2 つのレビューを追加した後のサンプル Web サイトの例を次に示します。
デプロイのトラブルシューティング
Web サイトにアクセスするためのアプリケーション URL を忘れた場合
Azure portal で次の手順を実行します。
- コンテナー アプリの
の [概要] ページに移動し、アプリケーション URL探します。
VS Code の場合:
- Azure ビュー (Ctrl + Shift + A) に移動し、作業中のサブスクリプションを展開します。
- Container Apps ノードを展開し、マネージド環境を展開します。python-container-app を右クリックして、[参照] を選択します。 VS Code は、アプリケーション URL を使用してブラウザーを開きます。
Azure CLI で次の手順を実行します。
- コマンド
az containerapp show -g pythoncontainer-rg -n python-container-app --query properties.configuration.ingress.fqdn
を使用します。
VS Code では、Azure のビルド イメージ タスクでエラーが返されます
"Error: failed to download context. VS Code 出力 ウィンドウで、URL が正しくないかどうかを確認してください。Docker 拡張機能でレジストリを更新します。 更新するには、Docker 拡張機能を選択し、レジストリ セクションに移動し、レジストリを見つけて選択します。
Azure タスクで
Azure portal で、コンテナー アプリの作成時にアクセス エラーが表示される
Azure Container Registry インスタンスで管理者資格情報が無効になっている際に、"ACR '<名>.azurecr.io' にアクセスできません" というアクセスエラーが発生します。
ポータルで管理者の状態を確認するには、Azure Container Registry インスタンスに移動し、リソース アクセス キー
コンテナー イメージが Azure Container Registry インスタンスに表示されない
- Azure CLI コマンドまたは VS Code 出力の出力を確認し、成功を確認するメッセージを探します。
- Azure CLI を使用したビルド コマンドまたは VS Code タスク プロンプトで、レジストリの名前が正しく指定されていることを確認します。
- 資格情報の有効期限が切れていないことを確認します。 たとえば、VS Code では、Docker 拡張機能でターゲット レジストリを見つけて更新します。 Azure CLI で、
az login
を実行します。
Web サイトから "Bad Request (400)" が返される
"Bad Request (400)" エラーが発生した場合は、コンテナーに渡された PostgreSQL 環境変数を確認します。 多くの場合、400 エラーは、Python コードが PostgreSQL インスタンスに接続できないことを示しています。
このチュートリアルで使用するサンプル コードでは、任意の値 (RUNNING_IN_PRODUCTION
など) に設定できるコンテナー環境変数 1
が存在するかどうかを確認します。
Web サイトから "Not Found (404)" が返されます
- コンテナーの [の概要] ページで、アプリケーション URL 値を確認します。 アプリケーション URL に "internal" という単語が含まれている場合、イングレスが正しく設定されていません。
- コンテナーのイングレスを確認します。 たとえば、Azure portal で、コンテナーの イングレス リソースに移動します。
HTTP イングレス が有効になっており、 どこからでもトラフィックを受け入れるが選択されていることを確認します。
Web サイトが起動しない、"ストリーム タイムアウト" が発生する、または何も返されない
- ログを確認します。
- Azure portal で、コンテナー アプリのリビジョン管理リソースに移動し、コンテナーのプロビジョニング状態
確認します。 - 状態が プロビジョニングの場合は、プロビジョニングが完了するまで待ちます。
- 状態が Failedの場合は、リビジョンを選択してコンソール ログを表示します。 列の順序を選択して、生成時刻、Stream_s、および Log_sを示します。 最新のログを並べ替え、
stderr
列で Pythonstdout
と メッセージを探します。 Pythonprint
出力はstdout
のメッセージです。
- Azure CLI で az containerapp logs show コマンドを使用します。
- Azure portal で、コンテナー アプリのリビジョン管理リソースに移動し、コンテナーのプロビジョニング状態
- Django フレームワークを使用している場合は、restaurants_reviews テーブルがデータベースに存在するかどうかを確認します。 存在しない場合は、コンソールを使用してコンテナーにアクセスして
python manage.py migrate
を実行します。
次のステップ
Azure Container Apps で Python Web アプリの継続的デプロイを構成する