デプロイのベスト プラクティス

開発チームごとに独自の要件があり、それによって、クラウド サービスで効率的なデプロイ パイプラインの実装が困難になる可能性があります。 この記事では、App Service へのデプロイにおける 3 つの主要なコンポーネントである、デプロイ ソース、ビルド パイプライン、およびデプロイ メカニズムについて説明します。 この記事では、特定の言語スタックのベスト プラクティスとヒントについても紹介します。

デプロイ コンポーネント

デプロイ ソース

デプロイ ソースは、アプリケーション コードの場所です。 運用アプリの場合、デプロイ ソースは通常、GitHub、BitBucket、Azure Repos などのバージョン管理ソフトウェアによってホストされるリポジトリです。 開発とテストのシナリオでは、デプロイ ソースはローカル コンピューター上のプロジェクトである可能性があります。

ビルド パイプライン

デプロイ ソースを決定したら、次の手順として、ビルド パイプラインを選択します。 ビルド パイプラインは、デプロイ ソースからソース コードを読み取り、一連の手順 (コードのコンパイル、HTML と JavaScript の縮小、テストの実行、コンポーネントのパッケージ化など) を実行して、アプリケーションを実行可能な状態にします。 ビルド パイプラインによって実行される特定のコマンドは、言語スタックによって異なります。 これらの操作は、Azure Pipelines などのビルド サーバーで実行することも、ローカルで実行することもできます。

デプロイ メカニズム

デプロイ メカニズムは、ビルドしたアプリケーションを Web アプリの /home/site/wwwroot ディレクトリに配置するために使用されるアクションです。 /wwwroot ディレクトリは、Web アプリのすべてのインスタンスによって共有される、マウントされたストレージの場所です。 デプロイ メカニズムによってアプリケーションがこのディレクトリに配置されると、インスタンスは新しいファイルを同期するための通知を受け取ります。 App Service では、次のデプロイ メカニズムをサポートしています。

  • Kudu エンドポイント:Kudu は、Windows App Service 内では独立したプロセスとして実行され、Linux App Service 内では 2 番目のコンテナーとして実行される、オープンソースの開発者生産性ツールです。 Kudu は、継続的なデプロイを処理し、zipdeploy などのデプロイ用の HTTP エンドポイントを提供します。
  • FTP と WebDeploy:サイトまたはユーザーの資格情報を使用して、FTP 経由または WebDeploy 経由でファイルをアップロードできます。 これらのメカニズムは、Kudu を経由しません。

Azure Pipelines、Jenkins、エディター プラグインなどのデプロイ ツールでは、これらのデプロイ メカニズムのいずれかを使用します。

デプロイ スロットの使用

新しい運用ビルドをデプロイするときは、可能な限り、デプロイ スロットを使用してください。 Standard App Service プラン レベル以上を使用している場合は、ステージング環境へのアプリのデプロイ、変更の検証、スモーク テストを行うことができます。 準備ができたら、ステージングおよび運用スロットを入れ替えることができます。 スワップ操作によって、必要なワーカー インスタンスが運用規模に合わせてウォームアップされるため、ダウンタイムがなくなります。

コードを継続的にデプロイする

テスト、QA、ステージング用に指定されたブランチがプロジェクトにある場合は、それらの各ブランチをステージング スロットに継続的にデプロイする必要があります。 これは Gitflow 設計と呼ばれます。これにより、関係者は、デプロイされたブランチを簡単に評価してテストすることができます。

運用スロットに対しては継続的デプロイを有効にしないでください。 代わりに、運用ブランチ (多くの場合、メイン) を非運用スロットにデプロイします。 ベース ブランチをリリースする準備ができたら、それを運用スロットにスワップします。 運用環境にデプロイするのではなく、運用環境にスワップすると、ダウンタイムの発生が抑えられ、もう一度スワップすることで変更をロールバックすることができます。

Diagram that shows the flow between the Dev, Staging, and Main branches and the slots they are deployed to.

コンテナーを継続的にデプロイする

Docker やその他のコンテナー レジストリのカスタム コンテナーの場合は、イメージをステージング スロットにデプロイし、運用環境にスワップしてダウンタイムを回避します。 イメージをコンテナー レジストリにプッシュし、webapp でイメージ タグを更新する必要があるため、オートメーションは、コードのデプロイよりも複雑になります。

スロットにデプロイするブランチごとに、ブランチへの各コミットで次を実行するようにオートメーションを設定します。

  1. イメージをビルドしてタグ付けする。 ビルド パイプラインの一部として、git のコミット ID、タイムスタンプ、またはその他の特定可能な情報でイメージにタグを付けます。 既定の "latest" タグは使用しないことをお勧めします。 そうしないと、現在デプロイされているコードの追跡が困難になり、デバッグがはるかに難しくなります。
  2. タグ付けされたイメージをプッシュする。 イメージがビルドされてタグ付けされると、パイプラインはイメージをコンテナー レジストリにプッシュします。 次の手順では、デプロイ スロットが、タグ付けされたイメージをコンテナー レジストリからプルします。
  3. デプロイ スロットを新しいイメージ タグで更新する。 このプロパティが更新されると、サイトは自動的に再起動して、新しいコンテナー イメージをプルします。

Slot usage visual

一般的なオートメーション フレームワークの例を以下に示します。

Azure DevOps を使用する

App Service には、デプロイ センターを介して、コンテナーの組み込みの継続的デリバリーがあります。 Azure portal でアプリに移動し、 [デプロイ] の下で [デプロイ センター] を選択します。 指示に従って、リポジトリとブランチを選択します。 これにより、選択したブランチに新しいコミットがプッシュされたときに、コンテナーを自動的にビルド、タグ付け、デプロイするように DevOps のビルドとリリースのパイプラインが構成されます。

GitHub Actions を使用する

GitHub Actions を使用して、コンテナーのデプロイを自動化することもできます。 次のワークフロー ファイルでは、コンテナーが作成されてコミット ID でタグ付けされ、コンテナー レジストリにプッシュされて、指定した Web アプリが新しいイメージ タグで更新されます。

on:
  push:
    branches:
    - <your-branch-name>

name: Linux_Container_Node_Workflow

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
    # checkout the repo
    - name: 'Checkout GitHub Action'
      uses: actions/checkout@main

    - uses: azure/docker-login@v1
      with:
        login-server: contoso.azurecr.io
        username: ${{ secrets.REGISTRY_USERNAME }}
        password: ${{ secrets.REGISTRY_PASSWORD }}

    - run: |
        docker build . -t contoso.azurecr.io/nodejssampleapp:${{ github.sha }}
        docker push contoso.azurecr.io/nodejssampleapp:${{ github.sha }} 

    - uses: azure/webapps-deploy@v2
      with:
        app-name: 'node-rnc'
        publish-profile: ${{ secrets.azureWebAppPublishProfile }}
        images: 'contoso.azurecr.io/nodejssampleapp:${{ github.sha }}'

他のオートメーション プロバイダーを使用する

前述の手順は、CircleCI や Travis CI などの他のオートメーション ユーティリティに適用されます。 ただし、最後の手順で、新しいイメージ タグでデプロイ スロットを更新するには、Azure CLI を使用する必要があります。 オートメーション スクリプトで Azure CLI を使用するには、次のコマンドを使用してサービス プリンシパルを生成します。

az ad sp create-for-rbac --name "myServicePrincipal" --role contributor \
   --scopes /subscriptions/{subscription}/resourceGroups/{resource-group} \
   --sdk-auth

スクリプトで、az login --service-principal を使用し、プリンシパルの情報を指定してサインインします。 次に、az webapp config container set を使用して、コンテナー名、タグ、レジストリ URL、レジストリ パスワードを設定します。 コンテナーの CI プロセスを構築するのに役立つリンクを次に示します。

言語固有の考慮事項

Java

JAR アプリケーションのデプロイには Kudu zipdeploy/ API を使用し、WAR アプリには wardeploy/ を使用してください。 Jenkins を使用している場合、デプロイ フェーズでこれらの API を直接使用できます。 詳細については、 こちらの記事を参照してください。

Node

既定では、Kudu は Node アプリケーションのビルド ステップ (npm install) を実行します。 Azure DevOps などのビルド サービスを使用している場合、Kudu ビルドは不要です。 Kudu ビルドを無効にするには、false の値を指定して SCM_DO_BUILD_DURING_DEPLOYMENT というアプリ設定を作成します。

.NET

既定では、Kudu は .NET アプリケーションのビルド ステップ (dotnet build) を実行します。 Azure DevOps などのビルド サービスを使用している場合、Kudu ビルドは不要です。 Kudu ビルドを無効にするには、false の値を指定して SCM_DO_BUILD_DURING_DEPLOYMENT というアプリ設定を作成します。

デプロイに関するその他の考慮事項

ローカル キャッシュ

Azure App Service のコンテンツは Azure Storage に保存され、コンテンツ共有として永続的な方法で表示されます。 ただし、アプリによっては、高可用で実行可能な高パフォーマンスの読み取り専用コンテンツ ストアのみが必要になる場合があります。 こうしたアプリは、ローカル キャッシュを使うことでメリットが得られます。 WordPress などのコンテンツ管理サイトには、ローカル キャッシュはお勧めしません。

ダウンタイムを防ぐために、必ずデプロイ スロットと共にローカル キャッシュを使用してください。 これらの機能を一緒に使用する方法については、こちらのセクションを参照してください。

CPU またはメモリの高い使用率

App Service プランで、使用可能な CPU またはメモリの 90% 以上が使用されている場合、基になる仮想マシンでのデプロイの処理に問題が発生する可能性があります。 これが発生している場合は、デプロイを実行するためにインスタンス数を一時的にスケールアップしてください。 デプロイが完了したら、インスタンス数を前の値に戻すことができます。

ベスト プラクティスの詳細については、App Service 診断にアクセスして、リソース専用の実行可能なベスト プラクティスを確認してください。

  • Azure portal で Web App に移動します。
  • 左側のナビゲーションで [問題の診断と解決] を選択すると、App Service 診断が開きます。
  • [ベスト プラクティス] ホームページ タイルを選択します。
  • [Best Practices for Availability & Performance] (可用性とパフォーマンスのベスト プラクティス) または [Best Practices for Optimal Configuration] (最適な構成のベスト プラクティス) を選び、これらのベスト プラクティスに関するアプリの現在の状態を確認します。

また、こちらのリンクを使用して、リソースの App Service 診断を直接開くこともできます: https://portal.azure.com/?websitesextension_ext=asd.featurePath%3Ddetectors%2FParentAvailabilityAndPerformance#@microsoft.onmicrosoft.com/resource/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{siteName}/troubleshoot

その他のリソース

環境変数とアプリ設定のリファレンス