Azure App ServiceでFastAPIが起動しない場合の対処方法 / Deploy FastAPI on Azure app service

# Azure App ServiceでFastAPIが起動しない場合の対処方法

GitHubのAzure-SamplesにあるFastAPIをAzure App Serviceで起動させたところ、正しく起動しない現象が発生しました。

https://github.com/Azure-Samples/msdocs-python-fastapi-webapp-quickstart

ローカル環境では以下のコマンドでFastAPIの起動が確認できたのですが。。。
```
python -m venv .venv
.\.venv\Scripts\activate.bat
pip install uvicorn
pip install gunicorn
pip install -r requirements.txt

uvicorn main:app --reload
```

### Azure App Serviceで起動すると以下のような画面が表示されて正常にFastAPIが起動していない現象になりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248463/89230b08-0258-bdfd-6f2b-647fa6974f65.png)

### ログを確認するとFrameworkが見つからないメッセージが見つかりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248463/a4627526-a386-fc01-3415-9bf8540748f6.png)

:::note alert
No framework detected; using default app from /opt/defaultsite
:::

### Startup Commandで起動スクリプトを直接設定する方法を試してみました。

```
/home/site/wwwroot/startup.sh
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248463/1f74f4ef-85c2-363f-a924-0a77fb6125b9.png)

### ログを確認すると指定したサービス名が見つからないエラーが発生していました。

ただし、ログの内容が変わったのでStartup Commandの変更は効果があるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248463/d6353654-5b26-5f27-0e63-b0cabe3dac83.png)

:::note alert
[Error -2] Name or service not known
:::

### Googleで検索したところ、StackOverflowに対処方法が見つかりました。

https://stackoverflow.com/questions/66251679/deploy-fastapi-and-uvicorn-on-azure-app-service

記事を読むとgunicornを使うと起動できるようです。

```
gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app
```

### Startup Commandで指定したstartup.shを修正して試してみました。

しかし、これでは正常に起動しませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248463/6fb152c2-8272-8f70-00f7-e21113c38883.png)

### 追記：/home/site/wwwroot/startup.shからstartup.shに変更したところ、この方法でも正常に起動しました。

どうも、zipファイルを展開した後のパスを直接指定する必要はないようです。

このブランチからクローンを作って、Startup CommandにStartup.shを設定する方法がシンプルかと思います。

https://github.com/kzkamiya/msdocs-python-fastapi-webapp-quickstart

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248463/abfb3c5e-6f82-913f-f247-bfee69f0eea6.png)

### Stackoverflowの記事と同じくStartup Commandへ直接gunicornを指定してみました。

```
gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248463/bacfa6ae-987f-89b1-35dd-434f9573b3df.png)

### ログを確認すると正常に起動してFastAPIの画面が確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248463/8aee2c34-d4e9-7313-9396-d49621f4c4e0.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248463/c984c385-5de4-59dc-3b8a-3cf07722ba50.png)

記事にはOryxはGunicornを使わないといけない説明がありました。

> Azure App Service for Linux with its Oryx build runner when identifies Python web apps run them  using Gunicorn, a WSGI server. So your startup script can have gunicorn command to spin up the  FastAPI app with the help of Gunicorn's worker class uvicorn.workers.UvicornWorker.

ChatGPTにOryxについて聞いてみるとOryxが自動的にランタイムを選択してくれるようですが、この機能がうまく動かなかったのが原因のようです。

> Oryx は、Microsoft Azureの一部として、特にAzure App ServiceやAzure Functionsでのアプリケーションのビルドと実行をサポートするためのツールです。Oryxは、複数のプログラミング言語とプラットフォームを自動的に検出してビルド・実行することができます。
たとえば、あなたがAzure App ServiceにNode.js、Python、.NET Core、PHP、Rubyなどのアプリケーションをデプロイするとき、Oryxはそのソースコードを適切にビルドし、適切なランタイムを選択して実行します。これにより、開発者はアプリケーションのデプロイに必要な具体的なビルド手順やランタイムの詳細を気にすることなく、簡単にアプリケーションをAzureにデプロイできるようになります。
Oryxは、これらのタスクを自動的に処理するためのビルドと実行の環境を提供し、Azure上でのアプリケーションのライフサイクルをシームレスにサポートします。

Azure App Serviceを使う場合にはOryxに気を付けたいと思います。
また、Azure App Service for LinuxとAzure App Service for Windowsでも挙動が変わりそうです。

> gunicornは、UNIXベースのシステムを対象としたWSGI HTTPサーバーであり、元々はLinuxやmacOSのようなUNIXベースの環境向けに設計されています。そのため、公式にはWindowsをサポートしていません。

あと、他にも以下のような対処方法があるようです。

https://stackoverflow.com/questions/65911260/azure-app-service-cannot-find-installed-modules/76028708#76028708

https://www.youtube.com/watch?v=oLdEI3zUcFg