Azure App Service(Node Stack) に Webサービス(NestJS)をデプロイする方法

## 最初に

趣味で作ったWebサービス(NestJS)を[Azure App Service](https://azure.microsoft.com/ja-jp/services/app-service/)に無料で公開する方法を記載します。
まず、Azure公式ドキュメント「[Azure で Node.js Web アプリを作成する](https://docs.microsoft.com/ja-jp/azure/app-service/quickstart-nodejs?pivots=platform-linux)」を参考に実施すると、素直に動作しました。
ですので、[NestJS](https://nestjs.com/) でも問題ないと思ってデプロイして、ブラウザで表示したら以下の **エラー** が表示されてしまいました。

![Azure Portal - create app service](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179413/ecc80812-e425-6aef-3af8-aeabb264db83.png)

## 代替手段の調査

うーん、困った…。  
誰か解決してくれていないかと検索したら、[Azure Functions](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-overview) にデプロイしている方と、[Azure Web App for Containers](https://azure.microsoft.com/ja-jp/services/app-service/containers/#overview)でDockerコンテナをデプロイしている方がいました。

* [Azure Functions の開発環境を NestJS で構築する方法](https://www.kadinche.com/azure-functions-%E3%81%AE%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83%E3%82%92-nestjs-%E3%81%A7%E6%A7%8B%E7%AF%89%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/)
* [ Node.js アプリを Azure App Service へ最適な形でデプロイする](https://blog.shibayan.jp/entry/20190807/1565161017)

どちらの方法も要件がマッチしていれば使いたいところでしたが、、、
Azure Functions を利用する方法だと、無料でできそうだけどWebサービス内のメモリキャッシュは使えるか？疑問に感じたので控えることにしました。
Dockerコンテナを利用する方法だと、コンテナをデプロイするためには有償の[Azure Container Registry](https://azure.microsoft.com/ja-jp/services/container-registry/)が必要となるようなので断念しました。  

## 解決手段

ソースを一部修正するのと、[Azure App Service](https://azure.microsoft.com/ja-jp/services/app-service/)の設定を一か所追加することで解決できました。
以降に私が動作確認した手順を記載します。

## NestJS初期化

NestJSを初期化するために、以下コマンドを実行します。

```txt
> npm i -g @nestjs/cli
> nest new websrv
```

![console - nest new websrv](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179413/e7ea99c9-cce9-64d1-c66b-a3cc099875ba.png)

実行後、以下のようなwebsrvフォルダが作成されます。

```txt
+---websrv
    +---node_modules
    +---src
        \---main.ts
    \---test
```

## NestJSソース修正

`src/main.ts`を修正します。

```typescript:src/main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // 元のソースコード
  // await app.listen(3000);

  // 追加したソースコード
  // Azure App Serviceはポート8080を利用する。
  // ポート番号は環境変数PORTで定義されているようなので、
  // 環境変数PORTを優先して利用するように修正する。
  const port = process.env.PORT || 3000;
  await app.listen(port);
}
bootstrap();
```

## ビルド

ソースの修正ができたら、ビルドします。

```
> npm run build
```

![console - npm run build](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179413/f7d66efc-9c9c-057a-0f4c-c41359aa39a1.png)

## Azure App Service作成

デプロイ先となる [Azure App Service](https://azure.microsoft.com/ja-jp/services/app-service/) を作成します。
作成後、[構成]->[全般の設定]->[スタートアップコマンド]に `node dist/main` を設定します。

2021-08-12追記: スタートアップコマンドに設定する以外に、package.json のstart スクリプトを `nest start` から `node dist/main` に変更してもよいです。

![Azure Portal - create app service settings](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179413/1de530ee-0680-3315-3660-496adea360c2.png)

## デプロイ

VSCodeのプラグイン「[Azure App Service for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azureappservice)」を使ってデプロイします。
具体的な手順は、「[Deploy to Azure (Azure へのデプロイ)](https://docs.microsoft.com/ja-jp/azure/app-service/quickstart-nodejs?pivots=platform-linux#deploy-to-azure)」を参照してください。

## 動作確認

ブラウザでAzure App ServiceのURLを開くと成功しました！

![Web Service success](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179413/02bd3274-da21-df93-5d53-b50aef5a03fb.png)