UVで作ったPythonアプリをAzure App Serviceにデプロイする手順の記録です
Steps
0. 前提
Ubuntu 24.04 で Python 3.13.11 で動かしています。
Python バージョン 3.9-3.13
1. プロジェクト初期設定
まずはプロジェクト作成。
uv init app-serv-uv -p 3.13
Package追加。
uv add fastapi --extra standard
uv add gunicorn
その後にコマンドパレットでPython Interpreter設定。
2. App Service リソース作成
VS Codeのコマンドパレットから「Azure App Service Create New Web App.. (Advanced)」を選択

以下の順序でApp Service リソース作成。
- リージョン選定
- default hostname format: Global default hostname を選択
- リソースグループ選択
- リソース名入力
- ランタイム: Python3.13選択
- App Service plan 登録を選択してリソース名入力
- App Service 価格プランの選択: Basic(B1)を選択
- Application Inssightsの選択: 既存であったやつを選択
3. Repository 作成
3.1. .vscode/settings.json作成
以下を設定。
※VS Code Extension用で、もしCLIで実行する場合は、不要かもしれません(未確認)。
-
appService.zipIgnorePattern: App Serviceにデプロイしない対象の定義 -
appService.defaultWebAppToDeploy: デフォルトのデプロイ App Service -
appService.deploySubpath: デプロイ対象のディレクトリ名
{
"appService.zipIgnorePattern": [
"__pycache__{,/**}",
"*.py[cod]",
"*$py.class",
".Python{,/**}",
"build{,/**}",
"develop-eggs{,/**}",
"dist{,/**}",
"downloads{,/**}",
"eggs{,/**}",
".eggs{,/**}",
"files{,/**}",
".files{,/**}",
"lib{,/**}",
"lib64{,/**}",
"parts{,/**}",
"sdist{,/**}",
"var{,/**}",
"wheels{,/**}",
"share/python-wheels{,/**}",
"*.egg-info{,/**}",
".installed.cfg",
"*.egg",
"MANIFEST",
".env{,/**}",
".venv{,/**}",
"env{,/**}",
"venv{,/**}",
"ENV{,/**}",
"env.bak{,/**}",
"venv.bak{,/**}",
".vscode{,/**}"
],
"appService.defaultWebAppToDeploy": "/subscriptions/<Subscription id>/resourceGroups/rg-acl-ncus/providers/Microsoft.Web/sites/<app service name>",
"appService.deploySubpath": "site",
"python-envs.pythonProjects": []
}
3.2. site ディレクトリ作成
siteディレクトリを作成し、ルートからいくつかファイルを移動し、以下のコマンド実行。
cd site
uv export --format requirements-txt > requirements.txt
.
├── README.md
└── site
├── main.py
├── .python-version
└── requirements.txt
Azure App Service 向けの Linux Python アプリを構成する- pyproject.toml with uv.lock: uvを使用します。には以下の記述があり、pyproject.toml と uv.lock が必要とあるのですが、
pyproject.toml with uv.lock: uvを使用します。
az webapps upコマンドを使う場合は、requirements.txtがあるとPythonとして検知してデプロイするそうなので、requirements.txtを作っています。多分、もっとスマートなやり方もあるはずです。VS Code Extension使うならルートディレクトリにあるpyproject.tomlとuv.lockをコピーするだけでも大丈夫。
Python detection looks for the existence of a file titled requirements.txt in the root folder of the project.
3.3.main.py作成
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI(title="FastAPI on Azure App Service (uv)")
class Item(BaseModel):
name: str
price: float
@app.get("/health")
def health():
return {"status": "ok"}
@app.get("/hello")
def hello(name: str = "world"):
return {"message": f"hello, {name}"}
@app.post("/items")
def create_item(item: Item):
return {"saved": item.model_dump()}
3.4. ローカルテスト
以下のコマンドでローカル実行します。
cd site
uv run uvicorn main:app --reload --port 8000
ブラウザで http://127.0.0.1:8000/health を見ると、{"status":"ok"}と表示され、
http://127.0.0.1:8000/docs で以下のようなSwagger UIが起動。

4. Azure Deploy
Azure App Serviceにデプロイ
APP_NAME="<App Service 名>"
RG_NAME="<リソースグループ名>"
SCM_DO_BUILD_DURING_DEPLOYMENT設定で、デプロイ時のビルド自動化。ついでにスタートアップも設定。
※何かを見てこの設定したのですが、デフォルト設定されていて不要かも
az webapp config appsettings set \
--resource-group "$RG_NAME" \
--name "$APP_NAME" \
--settings SCM_DO_BUILD_DURING_DEPLOYMENT=true
az webapp restart \
--resource-group "$RG_NAME" \
--name "$APP_NAME"
スタートアップの設定。
※ログ出力のために--access-logfile - --error-logfile - --capture-output --log-level infoを追加しましたが、この内容で正しいか未確認。
az webapp config set \
--startup-file "gunicorn -w 2 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000 main:app --access-logfile - --error-logfile - --capture-output --log-level info" \
--name "$APP_NAME" \
--resource-group "$RG_NAME"
※ここに手順記載していませんが、認証も追加しています。
5. デプロイ確認
Portal のメニュー デプロイ -> デプロイセンター の「ログ」タブから確認。
https://host/docs でSWAGGER UI も起動とAPIコール確認。


