Azure App Service の Python アプリ用のカスタム スタートアップ ファイルを構成する
この記事では、必要に応じて、Azure App Service でホストされている Python Web アプリのカスタム スタートアップ ファイルを構成する方法について説明します。 ローカルで実行する場合、スタートアップ ファイルは必要ありません。 ただし、Web アプリを Azure App Service にデプロイすると、コードは Docker コンテナーで実行され、スタートアップ コマンドが存在する場合はそれが使用される可能性があります。
カスタム スタートアップ ファイルは次の場合に必要です。
既定値 (
--bind=0.0.0.0 --timeout 600
) 以外の追加の引数を使って Gunicorn の既定の Web サーバーを起動したい。Flask および Django 以外のフレームワークを使用してアプリが作成されているか、または Gunicorn 以外の Web サーバーを使用したい。
Flask アプリのメイン コード ファイルに app.py または application.py* 以外の名前が付けられているか、アプリ オブジェクトに
app
以外の名前が付けられている。つまり、プロジェクトのルート フォルダーに app.py または application.py が存在し、"かつ" Flask アプリ オブジェクトの名前が
app
である場合以外は、カスタム スタートアップ コマンドが必要となります。
詳細については、Python アプリの構成 - コンテナーのスタートアップ プロセスに関する記事を参照してください。
スタートアップ ファイルを作成する
カスタム スタートアップ ファイルが必要な場合は、次の手順を使用します。
スタートアップ コマンドを含んだ startup.txt や startup.sh (または他の任意の名前) というファイルをプロジェクトに作成します。 Django や Flask などのフレームワークについて詳しくは、この記事の後続のセクションを参照してください。
スタートアップ ファイルには、必要に応じて複数のコマンドを含めることができます。
このファイルを、アプリの他のファイルと一緒にデプロイできるようコード リポジトリにコミットします。
Visual Studio Code で、アクティビティ バーの Azure アイコンを選択し、[リソース] を展開し、お使いのサブスクリプションを見つけて展開し、[App Services] を展開し、App Service を右クリックして、[ポータルで開く] を選択します。
Azure portal の [App Service] の [構成] ページで [全般設定] を選択し、スタートアップ ファイルの名前 (startup.txt または startup.sh など) を [スタックの設定]>[スタートアップ コマンド] の下に入力し、[保存] を選択します。
Note
スタートアップ コマンド ファイルを使用する代わりに、Azure portal の [スタートアップ コマンド] フィールドにスタートアップ コマンド自体を直接指定できます。 ただし、コマンド ファイルの使用をお勧めします。その理由は、これにより構成のこの部分をリポジトリに保存し、そこで変更を監査したり、別の App Service インスタンスにまとめて再デプロイしたりできるためです。
変更を保存すると、App Service が再起動されます。
ただし、まだアプリ コードをデプロイしていない場合、この時点でサイトにアクセスすると、"アプリケーション エラー" が表示されます。このメッセージは、Gunicorn サーバーが起動したがアプリを見つけることができなかったため、HTTP 要求に何も応答していないことを示します。
Django のスタートアップ コマンド
既定では、wsgi.py ファイルが格納されているフォルダーを App Service が自動的に特定し、次のコマンドで Gunicorn を起動します。
# <module> is the folder that contains wsgi.py. If you need to use a subfolder,
# specify the parent of <module> using --chdir.
gunicorn --bind=0.0.0.0 --timeout 600 <module>.wsgi
Gunicorn のいずれかの引数を変更したい場合は (--timeout 1200
を使用するなど)、それらの変更を含んだコマンド ファイルを作成します。 詳細については、「コンテナーのスタートアップ プロセス - Django アプリ」を参照してください。
Flask のスタートアップ コマンド
既定では、Flask アプリの WSGI 呼び出し可能型が app
という名前であり、アプリのルート フォルダーに application.py または app.py というファイル名で存在することを App Service on Linux コンテナーは想定しています。
次のいずれかの種類を使用している場合は、カスタム スタートアップ コマンドでアプリ オブジェクトの場所を file:app_object 形式で指定する必要があります。
ファイル名またはアプリ オブジェクト名が異なる: たとえば、アプリのメイン コード ファイルが hello.py で、アプリ オブジェクトの名前が
myapp
である場合、スタートアップ コマンドは次のようになります。gunicorn --bind=0.0.0.0 --timeout 600 hello:myapp
スタートアップ ファイルがサブフォルダーに存在する: たとえば、スタートアップ ファイルが myapp/website.py で、アプリ オブジェクトが
app
である場合、Gunicorn の--chdir
引数を使用してそのフォルダーを指定した後、通常どおりにスタートアップ ファイルとアプリ オブジェクトの名前を指定します。gunicorn --bind=0.0.0.0 --timeout 600 --chdir myapp website:app
スタートアップ ファイルがモジュール内に存在する: python-sample-vscode-flask-tutorial コードでは、webapp.py スタートアップ ファイルが hello_app フォルダーに格納されています。このフォルダーは、それ自体が __init__.py ファイルを含んだモジュールとなっています。 このアプリ オブジェクトは
app
という名前で、__init__.py で定義されています。また、webapp.py には、相対インポートが使用されています。このような配置のため、Gunicorn から
webapp:app
を参照すると "Attempted relative import in non-package (非パッケージでの相対インポートが試行されました)" というエラーが表示され、アプリは起動に失敗します。この状況では、モジュールからアプリ オブジェクトをインポートする shim ファイルを作成し、その shim を使用してアプリを起動するよう Gunicorn に命令します。 たとえば、python-sample-vscode-flask-tutorial コードには、次の内容を含んだ startup.py が存在します。
from hello_app.webapp import app
これで、スタートアップ コマンドは次のようになります。
gunicorn --bind=0.0.0.0 --workers=4 startup:app
詳細については、「コンテナーのスタートアップ プロセス - Flask アプリ」を参照してください。
その他のフレームワークと Web サーバー
Python アプリを実行する App Service コンテナーには、Django と Flask が Gunicorn Web サーバーと共に既定でインストールされています。
Django や Flask 以外のフレームワーク (Falcon、FastAPI など) を使用する場合、または異なる Web サーバーを使用する場合は、次を実行します。
対象のフレームワークまたは Web サーバーを requirements.txt ファイルに追加します。
先ほど Flask に関するセクションで取り上げた WSGI の呼び出し可能型をスタートアップ コマンドで特定します。
Gunicorn 以外の Web サーバーを起動するには、サーバーを直接呼び出す代わりに
python -m
コマンドを使用します。 たとえば、次のコマンドは、uvicorn サーバーを起動するものです。WSGI の呼び出し可能型はapp
という名前で、application.py に存在することを想定しています。python -m uvicorn application:app --host 0.0.0.0
python -m
を使用するのは、requirements.txt 経由でインストールされる Web サーバーは Python のグローバル環境には追加されず、直接呼び出すことができないためです。python -m
コマンドでは、現在の仮想環境内からサーバーが呼び出されます。