CI/CD と GitHub Actions を使用して Python Web アプリを Azure App Service on Linux にデプロイする

GitHub Actions継続的インテグレーションと継続的デリバリー (CI/CD) プラットフォームを使用して、Python Web アプリを Linux 上のAzure App Serviceにデプロイします。 GitHub Actions ワークフローでは、リポジトリへのコミットが発生するたびに、コードが自動的にビルドされ、App Serviceにデプロイされます。 テスト スクリプト、セキュリティ チェック、マルチステージデプロイなど、GitHub Actions ワークフローに他の自動化を追加できます。

アプリ コード用のリポジトリを作成する

使用する Python Web アプリが既にある場合は、GitHub リポジトリにコミットされていることを確認します。

作業するアプリが必要な場合は、https://github.com/Microsoft/python-sample-vscode-flask-tutorial でリポジトリをフォークしてクローンできます。 このコードは、Visual Studio Code での Flask に関するチュートリアルのものです。

Note

アプリで Django と SQLite データベースを使っている場合、このチュートリアルでは機能しません。 Django アプリで PostgreSQL などの別のデータベースを使用している場合は、このチュートリアルで使用できます。 Django の詳細については、この記事の後半の 「Django に関する考慮事項 」を参照してください。

ターゲット Azure App Serviceを作成する

App Service インスタンスを作成する最も簡単な方法は、対話型の Azure Cloud Shellを介して Azure コマンド ライン インターフェイス (CLI) を使用することです。 Cloud Shellには、Git と Azure CLI が含まれています。 次の手順では、az webapp up を使用して、App Serviceを作成し、アプリの最初のデプロイを行います。

手順 1. Azure Portal ( https://portal.azure.com ) にサインインします。

手順 2. ポータル のツール バーの [Cloud Shell] アイコンを選択して、Azure CLI を開きます。

Azure portalで Azure Cloud Shellを開く方法を示すスクリーンショット。

手順 3. Cloud Shellで、ドロップダウンから [Bash] を選択します。

Azure portalの Azure Cloud Shell Bash シェルを示すスクリーンショット。

手順 4. Cloud Shellで、git clone を使用してリポジトリを複製します。 たとえば、Flask サンプル アプリを使用している場合、コマンドは次のようになります。

git clone https://github.com/<github-user>/python-sample-vscode-flask-tutorial.git

github-user を>、リポジトリをフォークした GitHub アカウントの名前に置き換えます<。 別のアプリ リポジトリを使用している場合は、このリポジトリでGitHub Actionsを設定します。

Note

Cloud Shell は、cloud-shell-storage-<your-region> というリソース グループ内の Azure ストレージ アカウントによってサポートされています。 そのストレージ アカウントに含まれる Cloud Shell のファイル システムのイメージに、クローンされたリポジトリが格納されます。 このストレージにはわずかなコストがかかります。 この記事の最後で、作成した他のリソースと共に、そのストレージ アカウントを削除できます。

ヒント

Cloud Shell に貼り付けるには、Ctrl+Shift+V キーを使うか、右クリックしてコンテキスト メニューから [貼り付け] を選びます。

手順 5. Cloud Shellで、ディレクトリを Python アプリがあるリポジトリ フォルダーに変更して、az webapp up コマンドによってアプリが Python として認識されるようにします。 この例では、Flask サンプル アプリの場合は次のようになります。

cd python-sample-vscode-flask-tutorial

手順 6. Cloud Shellで、az webapp up を使用してApp Serviceを作成し、最初にアプリをデプロイします。

az webapp up --name <app-service-name> --runtime "PYTHON:3.9"

Azure で一意のApp Service名を指定します。 名前は 3 から 60 文字の長さにする必要があり、文字、数字、ハイフンのみを含めることができます。 名前の先頭は文字、末尾は文字または数字にする必要があります。

を使用して az webapp list-runtimes 、使用可能なランタイムの一覧を取得します。 形式を使用します PYTHON|X.Y 。ここで X.Y 、 は Python バージョンです。

パラメーターを使用して、App Serviceの場所を--location指定することもできます。 コマンドを az account list-locations --output table 使用して、使用可能な場所の一覧を取得します。

手順 7. アプリでカスタム スタートアップ コマンドを使用する場合は、 az webapp config でそのコマンドを使用します。 アプリにカスタム スタートアップ コマンドがない場合は、この手順をスキップします。

たとえば、 python-sample-vscode-flask-tutorial アプリには 、次 のように使用できるスタートアップ コマンドを含むstartup.txtという名前のファイルが含まれています。

az webapp config set \
  --resource-group <resource-group-name> \
  --name <app-service-name> \
  --startup-file startup.txt

リソース グループ名は、前 az webapp up のコマンドの出力から確認できます。 リソース グループ名は、azure-account-name>_rg_ で<始まります。

手順 8. 実行中のアプリを表示するには、ブラウザーを開き、http://< app-service-name.azurewebsites.net> に移動します。

汎用ページが表示される場合は、App Service が開始されるまで数秒待ってから、ページを更新します。 汎用ページが引き続き表示される場合は、正しいフォルダーからデプロイしたチェックします。 たとえば、Flask サンプル アプリを使用している場合、フォルダーは python-sample-vscode-flask-tutorial です。 また、Flask サンプル アプリの場合は、スタートアップ コマンドを正しく設定チェック。

App Serviceで継続的デプロイを設定する

次の手順では、継続的デプロイ (CD) を設定します。これは、ワークフローがトリガーされたときに新しいコード展開が行われることを意味します。 このチュートリアルでのトリガーは、pull request (PR) など、リポジトリの "メイン" ブランチに対する変更です。

手順 1. az webapp deployment github-actions add コマンドを使用して GitHub Action を追加します。

az webapp deployment github-actions add \
  --repo "<github-user>/<github-repo>" \
  --resource-group <resource-group-name> \
  --branch <branch-name> \
  --name <app-service-name> \
  --login-with-github

パラメーターは --login-with-github 、対話型メソッドを使用して個人用アクセス トークンを取得します。 プロンプトに従って認証を完了します。

App Service使用する名前と競合する既存のワークフロー ファイルがある場合は、上書きするかどうかを選択するように求められます。 パラメーターを --force 使用して、要求せずに上書きします。

add コマンドの動作:

  • リポジトリに .github/workflows/<workflow-name.yml> という新しいワークフロー ファイルを作成します。ファイルの名前には、App Serviceの名前が含まれます。
  • App Serviceのシークレットを含む発行プロファイルをフェッチし、GitHub アクション シークレットとして追加します。 シークレットの名前は、AZUREAPPSERVICE_PUBLISHPROFILE_で始まります。 このシークレットはワークフロー ファイルで参照されます。

手順 2. az webapp deployment source show コマンドを使用して、ソース管理デプロイ構成の詳細を取得します。

az webapp deployment source show \
  --name <app-service-name> \
  --resource-group <resource-group-name>

コマンドからの出力で、 プロパティと branch プロパティの値をrepoUrl確認します。 これらの値は、前の手順で指定した値と一致する必要があります。

GitHub ワークフローとアクションの説明

ワークフローは、リポジトリの /.github/workflows/ パスの YAML (.yml) ファイルによって定義されます。 この YAML ファイルには、ワークフローを構成するさまざまな手順とパラメーターが含まれています。これは、GitHub リポジトリに関連付けられた自動化されたプロセスです。 ワークフローを使用して、GitHub 上の任意のプロジェクトをビルド、テスト、パッケージ化、リリース、デプロイできます。

各ワークフローは、1 つ以上のジョブで構成されます。 各ジョブは一連のステップです。 最後に、各ステップはシェル スクリプトまたはアクションです。

App Serviceへのデプロイ用に Python コードを使用して設定されたワークフローに関しては、ワークフローには次のアクションがあります。

アクション 説明
Checkout ランナー (GitHub Actions エージェント) のリポジトリを確認します。
setup-python ランナーに Python をインストールします。
appservice-build Web アプリを作成します。
webapps-deploy 発行プロファイル資格情報を使用して Web アプリをデプロイし、Azure で認証します。 資格情報は GitHub シークレットに格納されます。

ワークフローの作成に使用されるワークフロー テンプレートは 、Azure/actions-workflow-samples です

ワークフローは、指定したブランチへのプッシュ イベントでトリガーされます。 イベントとブランチは、ワークフロー ファイルの先頭で定義されます。 たとえば、次のコード スニペットは、ワークフローが メイン ブランチへのプッシュ イベントでトリガーされていることを示しています。

on:
  push:
    branches:
    - main

OAuth 認証アプリ

継続的デプロイを設定すると、Azure App Serviceが GitHub アカウントに対して承認された OAuth アプリとして承認されます。 App Serviceは、承認されたアクセスを使用して、.github/workflows/<workflow-name.yml> に GitHub アクション YML ファイルを作成します。 承認されたアプリを表示し、GitHub アカウント の [設定] の [ 統合/アプリケーション] でアクセス許可を取り消すことができます。

GitHub アカウントの承認された OAuth アプリを表示する方法を示すスクリーンショット。

ワークフロー発行プロファイル シークレット

リポジトリに追加された .github/workflows/<workflow-name.yml> ワークフロー ファイルに、ワークフローのデプロイ ジョブに必要な発行プロファイル資格情報のプレースホルダーが表示されます。 発行プロファイル情報は、リポジトリ の [設定] の [ セキュリティ/アクション] に暗号化されて格納されます。

GitHub でアクション シークレットを表示する方法を示すスクリーンショット。

この記事では、GitHub アクションが発行プロファイル資格情報で認証されます。 サービス プリンシパルや OpenID Connect を使用して認証する方法は他にもあります。 詳細については、「GitHub Actionsを使用してApp Serviceにデプロイする」を参照してください。

ワークフローを実行する

次に、リポジトリを変更してワークフローをテストします。

手順 1. サンプル リポジトリ (または使用したリポジトリ) のフォークに移動し、トリガーの一部として設定したブランチを選択します。

GitHub Actions ワークフローが定義されているリポジトリとブランチに移動する方法を示すスクリーンショット。

手順 2. 小さな変更を加えよう。

たとえば、VS Code Flask チュートリアルを使用した場合、次のことができます。

  • トリガー ブランチの /hello-app/templates/home.html ファイルに移動します。
  • [ 編集] を 選択し、"Redeployed!" というテキストを追加します。

手順 3. 作業中のブランチに変更を直接コミットします。

  • 編集しているページの右上にある [ 変更のコミット ] ボタンを選択します。 [ 変更のコミット] ウィンドウが開きます。 [変更のコミット] ウィンドウで、必要に応じてコミット メッセージを変更し、[変更のコミット] ボタンを選択します。
  • コミットによって、GitHub Actions ワークフローが開始されます。

ワークフローを手動で開始することもできます。

手順 1. 継続的デプロイ用に設定されたリポジトリの [ アクション ] タブに移動します。

手順 2. ワークフローの一覧でワークフローを選択し、[ ワークフローの実行] を選択します。

失敗したワークフローのトラブルシューティング

ワークフローの状態を確認するには、リポジトリの [アクション] タブに移動します。 このチュートリアルで作成したワークフロー ファイルにドリルダウンすると、"ビルド" と "配置" の 2 つのジョブが表示されます。 失敗したジョブの場合は、ジョブ タスクの出力でエラーを示します。 いくつかの一般的な問題は次のとおりです。

  • 依存関係がないためにアプリが失敗した場合、 requirements.txt ファイルはデプロイ中に処理されませんでした。 この動作は、この記事で示すように az webapp up コマンドを使うのではなく、ポータルで Web アプリを直接作成した場合に発生します。

  • ポータルを使用してアプリ サービスをプロビジョニングした場合、ビルド アクションSCM_DO_BUILD_DURING_DEPLOYMENT設定が設定されていない可能性があります。 この設定は に設定する true必要があります。 コマンドは az webapp up 、ビルド アクションを自動的に設定します。

  • "TLS ハンドシェイク タイムアウト" というエラー メッセージが表示された場合は、リポジトリの [アクション] タブで [Trigger auto deployment] (自動デプロイのトリガー) を選択してワークフローを手動で実行し、タイムアウトが一時的な問題かどうかを確認します。

  • このチュートリアルに示すようにコンテナー アプリの継続的デプロイを設定すると、ワークフロー ファイル (.github/workflows/<workflow-name.yml>) が最初に自動的に作成されます。 変更した場合は、変更を削除して、エラーの原因かどうかを確認します。

配置後スクリプトを実行する

配置後スクリプトでは、たとえば、アプリ コードで必要な環境変数を定義できます。 アプリ コードの一部としてスクリプトを追加し、スタートアップ コマンドを使ってそれを実行します。

ワークフロー YML ファイルで変数値をハードコーディングしないようにするには、代わりに GitHub Web インターフェイスで変数値を指定し、スクリプト内の変数名を参照します。 暗号化されたシークレットは、リポジトリまたは環境 (アカウント リポジトリ) に対して作成できます。 詳細については、「 GitHub Docs の暗号化されたシークレット」を参照してください。

Django に関する考慮事項

この記事で前述したように、GitHub Actionsを使用して、別のデータベースを使用している場合は、Django アプリを Linux 上のAzure App Serviceにデプロイできます。 App Service は db.sqlite3 ファイルをロックし、読み取りと書き込みの両方を妨げるため、SQLite データベースを使うことはできません。 この動作は、外部データベースには影響しません。

App Service - コンテナーの起動プロセスで Python アプリを構成する」の記事で説明されているように、App Serviceはアプリ コード内で wsgi.py ファイルを自動的に検索します。このファイルには通常、アプリ オブジェクトが含まれます。 コマンドを webapp config set 使用してスタートアップ コマンドを設定した場合は、 パラメーターを --startup-file 使用して、アプリ オブジェクトを含むファイルを指定しました。 コマンドは webapp config set 、webapps-deploy アクションでは使用できません。 代わりに、 パラメーターを startup-command 使用してスタートアップ コマンドを指定できます。 たとえば、次のコード スニペットは、ワークフロー ファイルでスタートアップ コマンドを指定する方法を示しています。

startup-command: startup.txt

Django を使用する場合は、通常、アプリ コードをデプロイした後に コマンドを使用して python manage.py migrate データ モデルを移行します。 デプロイ後スクリプトで migrate コマンドを実行できます。

切断GitHub Actions

App ServiceからGitHub Actionsを切断すると、アプリのデプロイを再構成できます。 ファイルを保存または削除するかどうかに関係なく、切断後のワークフロー ファイルの動作を選択できます。

Azure CLI az webapp deployment github-actions remove コマンドを使用してGitHub Actionsを切断します。

az webapp deployment github-actions remove \
  --repo "<github-user>/<github-repo>" \
  --resource-group <resource-group-name> \
  --branch <branch-name> \
  --name <app-service-name> \
  --login-with-github

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

このチュートリアルで作成した Azure リソースで料金が発生しないようにするには、App Service と App Service プランを含むリソース グループを削除します。

Azure Cloud Shellを含む Azure CLI がインストールされている場所であれば、az group delete コマンドを使用してリソース グループを削除できます。

az group delete --name <resource-group-name>

少額の月額料金が発生する Cloud Shell 用のファイル システムを保持しているストレージ アカウントを削除するには、cloud-shell-storage- で始まるリソース グループを削除します。 グループの唯一のユーザーである場合は、リソース グループを削除しても安全です。 他のユーザーがいる場合は、リソース グループ内のストレージ アカウントを削除できます。

Azure リソース グループを削除した場合は、継続的デプロイ用に接続された GitHub アカウントとリポジトリに次の変更を加えることもできます。

  • リポジトリで 、.github/workflows/<workflow-name.yml> ファイルを 削除します。
  • リポジトリ設定で、ワークフロー用に作成されたAZUREAPPSERVICE_PUBLISHPROFILE_秘密鍵を削除します。
  • GitHub アカウント設定で、GitHub アカウントの承認された Oauth アプリとしてAzure App Serviceを削除します。