# Startup Commands by Framework Linux App Service (Oryx) auto-detects **Flask** and **Django** — no startup command is needed for these. **FastAPI does NOT rely on Oryx auto-detection** in this skill: we always set an explicit uvicorn startup command so the behavior is identical on every supported Python runtime (3.12, 3.13, 3.14, …). This skill also sets a startup command (or emits a manual hint) for non-Flask/Django/FastAPI frameworks. ## Flask — no startup command needed Azure App Service (Oryx) auto-detects Flask and starts it correctly. **Do not run `az webapp config set --startup-file` for Flask apps.** ## Django — no startup command needed Azure App Service (Oryx) auto-detects Django by finding `wsgi.py` and starts gunicorn against `.wsgi:application` automatically. **Do not run `az webapp config set --startup-file` for Django apps.** Make sure the project has: - `requirements.txt` containing `django` (and ideally `gunicorn`; Oryx provides one if missing) - `/wsgi.py` at a path Oryx can discover (the default Django layout works out of the box) - `ALLOWED_HOSTS` includes `.azurewebsites.net` (or `*` for first-deploy validation — tighten later) ## FastAPI — always set the uvicorn startup command The skill sets the startup command unconditionally for FastAPI, regardless of the Python runtime version. Oryx FastAPI auto-detection is **not** relied on — an explicit startup command always works and avoids version-dependent surprises: ```bash az webapp config set -n -g \ --startup-file "python -m uvicorn main:app --host 0.0.0.0" ``` ```powershell az webapp config set -n -g ` --startup-file "python -m uvicorn main:app --host 0.0.0.0" ``` Replace `main:app` with the discovered entry point if different (e.g., `app.main:app`, `src.api:app`). The `--host 0.0.0.0` flag is mandatory — uvicorn defaults to 127.0.0.1, which causes App Service container-ping timeouts. Make sure `requirements.txt` contains both `fastapi` and `uvicorn` (or `uvicorn[standard]`). ## Not auto-configured — warn & deploy anyway When the detected framework is `wsgi-generic`, `asgi-generic`, or `unknown`, **deploy the code without setting a startup command** and surface this message to the user: > ⚠️ This skill auto-configures Flask, Django, and FastAPI only. The app has been deployed, but App Service may not start it until you set a startup command. Choose the matching example below and run it: ### Generic WSGI ```bash az webapp config set -n -g \ --startup-file "gunicorn --bind=0.0.0.0 --timeout 600 :" ``` ```powershell az webapp config set -n -g ` --startup-file "gunicorn --bind=0.0.0.0 --timeout 600 :" ``` ### Generic ASGI ```bash az webapp config set -n -g \ --startup-file "python -m uvicorn : --host 0.0.0.0 --port 8000" ``` ```powershell az webapp config set -n -g ` --startup-file "python -m uvicorn : --host 0.0.0.0 --port 8000" ``` ### Django override (only if auto-detection fails) Oryx auto-detection covers the standard Django layout. Set this manually **only** if the project uses a non-standard layout and the auto-detected startup doesn't find your WSGI app: ```bash az webapp config set -n -g \ --startup-file "gunicorn --bind=0.0.0.0 --timeout 600 .wsgi" ``` ```powershell az webapp config set -n -g ` --startup-file "gunicorn --bind=0.0.0.0 --timeout 600 .wsgi" ``` ## Diagnosing a wrong startup command ```bash # Current value az webapp config show -n -g --query linuxFxVersion -o tsv az webapp config show -n -g --query appCommandLine -o tsv # Live logs az webapp log tail -n -g ``` Look for: - `Container _<...> didn't respond to HTTP pings on port: 8000` → app didn't bind to 0.0.0.0 (or 0.0.0.0:8000) - `ModuleNotFoundError` → wrong `:` in startup command, or build didn't install deps - `gunicorn: command not found` / `uvicorn: command not found` → add `gunicorn` / `uvicorn` to `requirements.txt` ## Why `--host 0.0.0.0` matters App Service forwards traffic to the container on the port the runtime listens on (8000 by default). The startup command must bind to `0.0.0.0` so the platform's ping reaches it — binding to `127.0.0.1` causes ping timeouts.