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 バージョンを表示するには、https://<sitename>.scm.azurewebsites.net/api/diagnostics/runtime にアクセスするか、https://<sitename>.scm.azurewebsites.net/api/diagnostics/runtime で次のコマンドを実行します。

az webapp list-runtimes --os windows | 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 --os 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="~16"

Note

この例では、推奨される "チルダ構文" を使用して、App Service で利用可能な最新バージョンの Node.js 16 ランタイムを対象にしています。

ランタイムはプラットフォームによって定期的に修正プログラムが適用され、更新されるので、特定のマイナーバージョン/パッチを対象にすることは推奨されません。これらは潜在的なセキュリティ リスクのため、使用可能であることが保証されていないからです。

Note

プロジェクトの 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|14-lts"

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

Note

プロジェクトの 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. npm run build 内でビルド スクリプトが指定されている場合、npm run build を実行します。
  4. npm run build:azure 内で build:azure スクリプトが指定されている場合、npm run build:azure を実行します。
  5. POST_BUILD_SCRIPT_PATH によって指定された場合、カスタム スクリプトを実行します。

Note

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 start、またはカスタム コマンドで開始するようにアプリを構成できます。

ツール 目的
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 ファイル

Note

Node 14 LTS 以降では、コンテナーは PM2 でアプリを自動的に起動しません。 PM2 でアプリを起動するには、スタートアップ コマンドを pm2 start <.js-file-or-PM2-file> --no-daemon に設定します。 コンテナーが正常に動作するには、PM2 をフォアグラウンドで実行する必要があるため、 引数 --no-daemon を必ず使用してください。

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

az webapp config set --resource-group <resource-group-name> --name <app-name> --startup-file "<filename-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 スクリプトが npm start ファイル内にあることを確認するだけです。 次に例を示します。

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

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

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

リモート デバッグ

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

ほとんどの場合、アプリ用に追加の構成は必要ありません。 アプリが 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 では、TLS または 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> --docker-container-logging filesystem --level Verbose

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

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

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

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

Note

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 でログ ファイルを検査することもできます。

URL の書き換え

Node.js アプリを Azure App Service for Linux にデプロイする場合は、アプリケーション内で直接 URL の書き換え処理を行う必要がある場合があります。 これは、Web サーバーの構成に依存せずに、特定の URL パターンが正しいエンドポイントにリダイレクトされるようにするために特に便利です。 Node.js で URL の書き換えを行うには、いくつかの方法があります。 たとえば、express-urlrewrite パッケージです。

Application Insights での監視

Application Insights を使用すると、コードを変更することなく、アプリケーションのパフォーマンス、例外、使用状況を監視できます。 Application Insights エージェントをアタッチするには、ポータルで自分の Web アプリにアクセスし、[設定][Application Insights] を選択してから、[Application Insights を有効にする] を選択します。 次に、既存の Application 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 アプリ設定を指定することによって、実行時に開発モードにアプリを設定できます。

このディレクトリまたはページを表示するアクセス許可がない

App Service でネイティブ Windows アプリに Node.js コードをデプロイした後、アプリの URL に移動すると、ブラウザーに You do not have permission to view this directory or page というメッセージが表示される場合があります。 これは、web.config ファイルが見つからないことが原因である可能性があります。 (テンプレートを参照してください。)

Git を使用してファイルをデプロイした場合、またはビルドの自動化を有効にして ZIP デプロイを使用した場合、以下のいずれかの条件が満たされると、展開エンジンによって、アプリの Web ルート () に、web.config%HOME%\site\wwwroot が自動的に生成されます。

  • プロジェクト ルートに、JavaScript ファイルのパスを含む start スクリプトを定義する、package.json が含まれている。
  • プロジェクト ルートに、server.js または app.js のいずれかが含まれている。

生成された web.config は、検出された開始スクリプトに合わせて調整されています。 その他のデプロイ方法の場合は、この web.config を手動で追加してください。 ファイルが適切に書式設定されていることを確認します。

ZIP デプロイを (Visual Studio Code などで) 使用する場合は、必ずビルドの自動化を有効にするようにしてください。 これは、既定では有効になっていません。 az webapp up では、ビルドの自動化が有効になっている ZIP デプロイを使用します。

ログの 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 に知らせます。

次のステップ

または、その他のリソースを参照してください。

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