Azure App Service 向けの Node.js アプリを構成する

Node.js アプリは、必要なすべての NPM 依存関係と共にデプロイする必要があります。 App Service 展開エンジンは、Git リポジトリをデプロイするとき、またはビルド自動化が有効になっている Zip パッケージをデプロイするときに、npm install --production を自動的に実行します。 ただし、FTP/S を使用してファイルをデプロイする場合、必要なパッケージを手動でアップロードする必要があります。

このガイドでは、App Service にデプロイする Node.js 開発者向けに主要な概念と手順を説明します。 Azure App Service を使用したことがない場合は、まず、Node.js クイック スタートMongoDB を使った Node.js のチュートリアルに従ってください。

Node.js のバージョンを表示する

現在の Node.js バージョンを表示するには、Cloud Shell で次のコマンドを実行します。

az webapp config appsettings list --name <app-name> --resource-group <resource-group-name> --query "[?name=='WEBSITE_NODE_DEFAULT_VERSION'].value"

サポートされているすべての Node.js バージョンを表示するには、Cloud Shell で次のコマンドを実行します。

az webapp list-runtimes | grep node

現在の Node.js バージョンを表示するには、Cloud Shell で次のコマンドを実行します。

az webapp config show --resource-group <resource-group-name> --name <app-name> --query linuxFxVersion

サポートされているすべての Node.js バージョンを表示するには、Cloud Shell で次のコマンドを実行します。

az webapp list-runtimes --linux | grep NODE

Node.js のバージョンを設定する

サポートされている Node.js バージョンにアプリを設定するには、Cloud Shell で次のコマンドを実行して、WEBSITE_NODE_DEFAULT_VERSION をサポートされているバージョンに設定します。

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings WEBSITE_NODE_DEFAULT_VERSION="10.15"

この設定では、実行時と、App Service のビルド自動化中のパッケージの自動復元時の両方で使用する Node.js のバージョンを指定します。

注意

プロジェクトの package.json で Node.js バージョンを設定する必要があります。 展開エンジンは、サポートされているすべての Node.js バージョンを含む別のプロセスで実行されます。

サポートされているすべての Node.js バージョンにアプリを設定するには、Cloud Shell で次のコマンドを実行します。

az webapp config set --resource-group <resource-group-name> --name <app-name> --linux-fx-version "NODE|10.14"

この設定では、実行時と、Kudu でのパッケージの自動復元中の両方で使用する Node.js のバージョンを指定します。

注意

プロジェクトの package.json で Node.js バージョンを設定する必要があります。 デプロイ エンジンは、サポートされているすべての Node.js バージョンを含む別のコンテナーで実行します。

ポート番号を取得する

Node.js アプリでは、受信要求を受信するために適切なポートがリッスンされる必要があります。

Windows の App Service では、IISNode を使用して Node.js アプリがホストされるため、Node.js アプリでは process.env.PORT 変数で指定されたポートがリッスンされる必要があります。 次の例は、単純な簡易アプリで行う方法を示しています。

App Service では、Node.js コンテナーに環境変数 PORT が設定され、そのポート番号で受信要求がコンテナーに転送されます。 要求を受信するには、アプリで process.env.PORT を使用して、そのポートがリッスンされる必要があります。 次の例は、単純な簡易アプリで行う方法を示しています。

const express = require('express')
const app = express()
const port = process.env.PORT || 3000

app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

ビルドの自動化のカスタマイズ

ビルドの自動化を有効にして Git または zip パッケージを使用してアプリをデプロイする場合、App Service のビルドの自動化によって、次の手順が実行されます。

  1. PRE_BUILD_SCRIPT_PATH によって指定された場合、カスタム スクリプトを実行します。
  2. フラグを指定せずに npm install を実行します。これには、npm preinstall スクリプトと postinstall スクリプトが含まれ、devDependencies のインストールも行われます。
  3. package.json 内でビルド スクリプトが指定されている場合、npm run build を実行します。
  4. package.json 内で build:azure スクリプトが指定されている場合、npm run build:azure を実行します。
  5. POST_BUILD_SCRIPT_PATH によって指定された場合、カスタム スクリプトを実行します。

注意

npm に関するドキュメントに説明されているように、prebuild および postbuild というスクリプトが指定された場合、それぞれ buildの前と後に実行されます。 preinstall および postinstall はそれぞれ、install の前と後に実行されます。

PRE_BUILD_COMMAND および POST_BUILD_COMMAND は、既定では空の環境変数です。 ビルド前のコマンドを実行するには、PRE_BUILD_COMMAND を定義します。 ビルド後のコマンドを実行するには、POST_BUILD_COMMAND を定義します。

次の例では、一連のコマンドに対して 2 つの変数をコンマ区切りで指定しています。

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings PRE_BUILD_COMMAND="echo foo, scripts/prebuild.sh"
az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings POST_BUILD_COMMAND="echo foo, scripts/postbuild.sh"

ビルドの自動化をカスタマイズするためのその他の環境変数については、「Oryx の構成」を参照してください。

Linux 上で App Service によって Node.js アプリが実行されビルドされる方法に関する詳細については、Oryx ドキュメントの Node.js アプリが検出されビルドされる方法に関するページを参照してください。

Node.js サーバーを構成する

Node.js コンテナーには、製造工程マネージャーである PM2 が付属しています。 PM2、NPM、またはカスタム コマンドで開始するようにアプリを構成できます。

ツール 目的
PM2 で実行する 推奨 - 運用またはステージングでの使用。 PM2 がフルサービス アプリ管理プラットフォームを提供します。
npm start を実行する 開発での使用のみ。
カスタム コマンドを実行する 開発またはステージング。

PM2 で実行する

コンテナーは、一般的な Node.js ファイルの 1 つがプロジェクトで見つかった場合、PM2 でアプリを自動的に開始します。

  • bin/www
  • server.js
  • app.js
  • index.js
  • hostingstart.js
  • 次のいずれかの PM2 ファイル: process.json および ecosystem.config.js

次の拡張子を持つカスタム スタート ファイルを構成することもできます。

  • .js ファイル
  • .json. config.js.yaml、または .yml の拡張子を持つ PM2 ファイル

カスタム スタート ファイルを追加するには、Cloud Shell で次のコマンドを実行します。

az webapp config set --resource-group <resource-group-name> --name <app-name> --startup-file "<filname-with-extension>"

カスタム コマンドを実行する

App Service は、run.sh のような実行可能ファイルなどのカスタム コマンドを使用してアプリを開始できます。たとえば、npm run start:prod を実行するには、Cloud Shell で次のコマンドを実行します。

az webapp config set --resource-group <resource-group-name> --name <app-name> --startup-file "npm run start:prod"

npm start を実行する

npm start を使用してをアプリを開始するには、start スクリプトが package.json ファイル内にあることを確認するだけです。 次に例を示します。

{
  ...
  "scripts": {
    "start": "gulp",
    ...
  },
  ...
}

プロジェクトでカスタム package.json を使用するには、Cloud Shell で次のコマンドを実行します。

az webapp config set --resource-group <resource-group-name> --name <app-name> --startup-file "<filename>.json"

リモート デバッグ

注意

リモート デバッグは、現在、プレビュー段階です。

PM2 で実行するように構成した場合、.config.js、.yml、または .yaml を使用して実行したときを除き、Visual Studio Code で Node.js アプリをリモートからデバッグできます。

ほとんどの場合、アプリ用に追加の構成は必要ありません。 アプリが process.json ファイル (既定またはカスタム) で実行されている場合、JSON ルートに script プロパティが必要です。 次に例を示します。

{
  "name"        : "worker",
  "script"      : "./index.js",
  ...
}

リモート デバッグ用に Visual Studio Code を設定するには、App Service 拡張機能をインストールします。 拡張機能ページの指示に従い、Visual Studio Code で Azure にサインインします。

Azure エクスプローラーで、デバッグするアプリを見つけ、それを右クリックして、[リモート デバッグを開始する] を選択します。 [はい] をクリックしてアプリに対して有効にします。 App Service により、トンネル プロキシが開始され、デバッガがアタッチされます。 続いて、アプリに対して要求を行って、ブレーク ポイントで中断しているデバッガを確認できます。

デバッグが完了すると、[切断] を選択してデバッガを停止します。 求められたら、[はい] をクリックしてリモート デバッグを無効にする必要があります。 後で無効にするには、Azure エクスプローラーでもう一度アプリを右クリックし、[リモート デバッグの無効化] を選択します。

環境変数へのアクセス

App Service では、アプリ コードの外部でアプリ設定を指定できます。 その後、標準の Node.js パターンを使用して、それらにアクセスできます。 たとえば、NODE_ENV というアプリ設定にアクセスするには、次のコードを使用します。

process.env.NODE_ENV

Grunt/Bower/Gulp を実行する

既定では、App Service のビルド自動化によって、Node.js アプリが Git またはビルド自動化が有効になっている Zip デプロイを介してデプロイされることが認識されると、npm install --production が実行されます。 アプリで、Grunt、Bower、Gulp など、一般的な自動化ツールのいずれかが必要な場合、それを実行するカスタム デプロイ スクリプトを提供する必要があります。

リポジトリでこれらのツールを実行できるようにするには、package.json での依存関係にこれらを追加する必要があります。 次に例を示します。

"dependencies": {
  "bower": "^1.7.9",
  "grunt": "^1.0.1",
  "gulp": "^3.9.1",
  ...
}

ローカル ターミナル ウィンドウから、ディレクトリをリポジトリのルートに変更し、次のコマンドを実行します。

npm install kuduscript -g
kuduscript --node --scriptType bash --suppressPrompt

リポジトリのルートには現在、 .deploymentdeploy.sh の 2 つの追加ファイルがあります。

deploy.sh を開き、次のような Deployment セクションを見つけます。

##################################################################################################################################
# Deployment
# ----------

このセクションは、npm install --production の実行で終わります。 Deployment セクションの 末尾 に必要なツールの実行に必要なコード セクションを追加します。

MEAN.js サンプルでの例を参照してください。ここでは、デプロイ スクリプトはカスタム npm install コマンドも実行します。

Bower

このスニペットは bower install を実行します。

if [ -e "$DEPLOYMENT_TARGET/bower.json" ]; then
  cd "$DEPLOYMENT_TARGET"
  eval ./node_modules/.bin/bower install
  exitWithMessageOnError "bower failed"
  cd - > /dev/null
fi

Gulp

このスニペットは gulp imagemin を実行します。

if [ -e "$DEPLOYMENT_TARGET/gulpfile.js" ]; then
  cd "$DEPLOYMENT_TARGET"
  eval ./node_modules/.bin/gulp imagemin
  exitWithMessageOnError "gulp failed"
  cd - > /dev/null
fi

Grunt

このスニペットは grunt を実行します。

if [ -e "$DEPLOYMENT_TARGET/Gruntfile.js" ]; then
  cd "$DEPLOYMENT_TARGET"
  eval ./node_modules/.bin/grunt
  exitWithMessageOnError "Grunt failed"
  cd - > /dev/null
fi

HTTPS セッションの検出

App Service では、SSL 終了がネットワーク ロード バランサーで発生するため、すべての HTTPS リクエストは暗号化されていない HTTP リクエストとしてアプリに到達します。 ユーザー要求が暗号化されているかどうかをアプリ ロジックが確認する必要がある場合は、X-Forwarded-Proto ヘッダーを調べます。

一般的な Web フレームワークでは、標準のアプリ パターンで X-Forwarded-* 情報にアクセスできます。 Express で、trust proxy を使用できます。 次に例を示します。

app.set('trust proxy', 1)
...
if (req.secure) {
  // Do something when HTTPS is used
}

診断ログにアクセスする

App Service のアプリケーション コード内から生成されたコンソール ログにアクセスするには、Cloud Shell で次のコマンドを実行して、診断ログを有効にします。

az webapp log config --resource-group <resource-group-name> --name <app-name> --application-logging true --level Verbose

--level で有効な値は、ErrorWarningInfo、および Verbose です。 後続の各レベルには、前のレベルが含まれます。 たとえば、Error にはエラー メッセージのみが含まれ、Verbose にはすべてのメッセージが含まれます。

診断ログがオンになったら、次のコマンドを実行して、ログのストリームを確認します。

az webapp log tail --resource-group <resource-group-name> --name <app-name>

コンソール ログがすぐに表示されない場合は、30 秒以内にもう一度確認します。

注意

https://<app-name>.scm.azurewebsites.net/api/logs/docker で、ブラウザーからログ ファイルを検査することもできます。

任意のタイミングでログのストリーミングを停止するには、Ctrl+C と入力します。

コンテナー内から生成されたコンソール ログにアクセスできます。

まず、次のコマンドを実行して、コンテナーのログ記録をオンにします。

az webapp log config --name <app-name> --resource-group <resource-group-name> --docker-container-logging filesystem

<app-name><resource-group-name> は、Web アプリに適した名前に置き換えます。

コンテナーのログ記録がオンになったら、次のコマンドを実行して、ログのストリームを確認します。

az webapp log tail --name <app-name> --resource-group <resource-group-name>

コンソール ログがすぐに表示されない場合は、30 秒以内にもう一度確認します。

任意のタイミングでログのストリーミングを停止するには、Ctrl+C キーを押します。

ブラウザーから https://<app-name>.scm.azurewebsites.net/api/logs/docker でログ ファイルを検査することもできます。

Application Insights での監視

Application Insights を使用すると、コードを変更することなく、アプリケーションのパフォーマンス、例外、使用状況を監視できます。 App Insights エージェントをアタッチするには、ポータルで自分の Web アプリにアクセスし、 [設定][Application Insights] を選択してから、 [Turn on Application Insights](Application Insights を有効にする) を選択します。 次に、既存の App Insights リソースを選択するか、新しいものを作成します。 最後に、下部にある [適用] を選択します。 PowerShell を使用して Web アプリをインストルメント化するには、これらの手順を参照してください。

このエージェントは、サーバー側の Node.js アプリケーションを監視します。 クライアント側の JavaScript を監視するには、JavaScript SDK をプロジェクトに追加します

詳細については、Application Insights の拡張機能のリリース ノートを参照してください。

トラブルシューティング

動作中の Node.js アプリが App Service で異なる動作をしたり、エラーが発生した場合は、次のことを試してください。

  • ログ ストリームにアクセスします。
  • 実稼働モードでローカルにアプリをテストします。 App Service では、実稼働モードで Node.js アプリが実行されるので、プロジェクトがローカルで実稼働モードで予想どおりに動作することを確認する必要があります。 次に例を示します。
    • package.json に応じて、実稼働モードに別々のパッケージ (dependenciesdevDependencies) がインストールされる場合があります。
    • 特定の Web フレームワークでは、実稼働モードで静的ファイルを別にデプロイすることがあります。
    • 特定の Web フレームワークでは、実稼働モードで実行しているときにカスタム スタートアップ スクリプトを使用することがあります。
  • 開発モードの App Service でアプリを実行します。 たとえば、MEAN.js で、NODE_ENV アプリ設定を指定することによって、実行時に開発モードにアプリを設定できます。

ログの robots933456

コンテナー ログで次のメッセージが表示されることがあります。

2019-04-08T14:07:56.641002476Z "-" - - [08/Apr/2019:14:07:56 +0000] "GET /robots933456.txt HTTP/1.1" 404 415 "-" "-"

このメッセージは無視してかまいません。 /robots933456.txt は、コンテナーが要求を処理できるかどうかを調べるために App Service が使用するダミーの URL パスです。 404 応答は、パスが存在しないことを示すだけですが、コンテナーが正常であり、要求に応答できる状態であることを App Service に知らせます。

次のステップ