当サイトは、アフィリエイト広告を利用しています
fastapi製のアプリケーションを動かす際によく使われる
ASGI(Synchronous Server Gateway Interface)サーバのuvicornの
起動方法を調べてたのでまとめる
uvicornの起動方法を大きく
の2種類がある。
uvicornをコマンドラインから起動する方法
dockerコンテナ内でfastapiアプリケーションをuvicornで起動する場合の
起動コマンドサンプル
uvicorn app.asgi:app --reload --host 0.0.0.0 --port 8000
細かく解説すると
fastapiのアプリケーションインスタンスのパスを指定
ソースに変更があった場合に再起動する
※いわゆるホットリロード
ちなみにhost指定なしで起動すると127.0.0.1(ローカルホスト)で起動してしまう。
127.0.0.1(ローカルホスト)は「コンテナ内部の 127.0.0.1 で待ち受ける」ことであり
ホストOSはコンテナの外なのでアクセスできない。
※IPアドレスを0.0.0.0(すべてのIPアドレスを受け付ける)
ocalhost:8000 でコンテナ内のアプリにアクセスできる
コマンドライン起動の利点としては下記がある
uvicornをPython内で起動する方法
dockerコンテナ内でfastapiアプリケーションをuvicornで起動する場合の
起動スクリプトのサンプル
import uvicornfrom uvicorn_config import configif __name__ == "__main__":# uvicorn起動uvicorn.run("asgi:app",host="0.0.0.0",port=8000,reload=True,)
それぞれの引数の意味については
コマンドライン起動と同じ。
スクリプト起動の利点としては下記がある
fastap製のREST APIでuvicornのコマンドライン起動を試してみる
.|-- app| |-- __init__.py| |-- asgi.py| |-- endpoints.py| `-- main.py|-- docker-compose.yml|-- dockerfile`-- requirements.txt
簡易なfastapi製のREST APIをdockerコンテナ上で作成する
fastapi==0.115.6uvicorn[standard]==0.34.0
最低限必要なパッケージを設定
FROM python:3.12# PYTHONPATHの設定ENV PYTHONPATH=/workspace/app# workspaceディレクトリ作成、移動WORKDIR /workspace# プロジェクトディレクトリにコピーCOPY requirements.txt /workspace# 必要パッケージのインストールRUN pip install --upgrade pipRUN pip install -r requirements.txt
requirements.txtで設定したパッケージをインストールしたdockerイメージを
作成する。
version: "3"services:uvicorn-start:container_name: "uvicorn-start"build:context: .dockerfile: Dockerfilevolumes:- .:/workspacetty: trueports:- 8000:8000 # ホストマシンのポート8000を、docker内のポート8000に接続する# command:# ["uvicorn", "asgi:app", "--reload", "--host", "0.0.0.0", "--port", "8000"]
dockerfileで作ったイメージを元にコンテナを作成する
コンテナ起動と同時にuvicornを起動する場合は「command」部分のコメントアウトを解除する
手動で起動や停止したい場合は、コメントアウトのままにする
from fastapi import FastAPIimport loggingimport endpoints as endpointsdef create_app():# アプリケーションインスタンスの作成app = FastAPI()# ルーティング設定app.include_router(endpoints.router)return app
アプリケーションの初期化処理を行うモジュール
from main import create_appapp = create_app()
FastApiアプリケーションをASGIサーバーで起動するための エントリーポイントとなるモジュール
コマンドライン起動のオプションでこのモジュールのapp(fastapiアプリケーションインスタンス)を指定する
import loggingfrom fastapi import APIRouterfrom fastapi.responses import JSONResponserouter = APIRouter()# ディクショナリusers = [{"user_id": "1", "name": "Tujimura", "age": 11},{"user_id": "2", "name": "mori", "age": 20},{"user_id": "3", "name": "shimada", "age": 501},{"user_id": "4", "name": "kyogoku", "age": 70}]# ユーザー一覧を取得@router.get("/")async def get_users():return JSONResponse(status_code=211, content=users)
エンドポイントを管理するモジュール。 GETのエンドポイントを作成しておく
$ docker compose up -d$ docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES9e575d48ad46 fastapi_uvicorn_start_pattern-uvicorn-start "uvicorn asgi:app --…" 21 seconds ago Up 14 seconds 0.0.0.0:8000->8000/tcp uvicorn-start
$ docker exec -it uvicorn-start sh#
上記ではコマンドラインからコンテナにアタッチしてるが
VSCodeからリモートでコンテナに接続する場合はVSCodeの拡張機能で
のどちらかを使用すれば、コンテナ内をVSCodeから操作できる ※この拡張機能はホスト側のVSCodeでインストールして使う
$ docker exec -it uvicorn-start sh# 起動# uvicorn asgi:app --reload --host 0.0.0.0 --port 8000INFO: Will watch for changes in these directories: ['/workspace']INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)INFO: Started reloader process [13] using WatchFilesINFO: Started server process [15]INFO: Waiting for application startup.INFO: Application startup complete.# 停止^CINFO: Shutting downINFO: Waiting for application shutdown.INFO: Application shutdown complete.INFO: Finished server process [20]INFO: Stopping reloader process [18]
正常に起動する。
停止する時はctrl + c で止める
起動中にホスト側からcurlコマンドでGETリクエストを投げるとレスポンスが返ってくる
$ curl -i -X GET http://localhost:8000HTTP/1.1 211date: Sat, 22 Feb 2025 15:42:18 GMTserver: uvicorncontent-length: 168content-type: application/json[{"user_id":"1","name":"Tujimura","age":11},{"user_id":"2","name":"mori","age":20},{"user_id":"3","name":"shimada","age":501},{"user_id":"4","name":"kyogoku","age":70}]
毎回コマンドを打つのが面倒であれば、上記でも書いたが
docker-compose.ymlでコンテナ作成時に起動する、または
VScodeのタスクに登録すればショートカット起動することができる。
VSCodeのタスクに登録しておく。手順は下記の通り
上記を実行すると.vscode/task.jsonが作成されるので 下記ように書き換える
{"version": "2.0.0","tasks": [{"label": "Run Uvicorn","type": "process","command": "uvicorn","args": ["asgi:app","--reload","--host","0.0.0.0","--port","8000"],"problemMatcher": [],"group": {"kind": "build","isDefault": true}}]}
VScodeのタスクなので、このタスクを実行するためには
コマンドではなく、拡張機能Dev ContainersかDockerを使ってVSCodeからコンテナにアタッチする必要がある
次はfastap製のREST APIでuvicornのPythonスクリプト起動を試してみる
.|-- app| |-- __init__.py| |-- asgi.py| |-- endpoints.py| `-- main.py|-- docker-compose.yml|-- dockerfile|-- requirements.txt|-- start_uvicorn.py`-- uvicorn_config.py
コマンドライン起動と同様に簡易なfastapi製のREST APIをdockerコンテナ上で作成する
fastapi==0.115.6uvicorn[standard]==0.34.0
最低限必要なパッケージを設定
FROM python:3.12# PYTHONPATHの設定ENV PYTHONPATH=/workspace/app# workspaceディレクトリ作成、移動WORKDIR /workspace# プロジェクトディレクトリにコピーCOPY requirements.txt /workspace# 必要パッケージのインストールRUN pip install --upgrade pipRUN pip install -r requirements.txt
requirements.txtで設定したパッケージをインストールしたdockerイメージを
作成する。
version: "3"services:uvicorn-start:container_name: "uvicorn-start"build:context: .dockerfile: Dockerfilevolumes:- .:/workspacetty: trueports:- 8000:8000 # ホストマシンのポート8000を、docker内のポート8000に接続するentrypoint: ["python", "start_uvicorn.py"]
dockerfileで作ったイメージを元にコンテナを作成する
コンテナ起動時にuvicorn起動用のpythonスクリプトが実行されるように
entrypointで指定する
app配下のモジュールの
についてはコンテナ起動と同じのため割愛する。
# uvicorn起動設定config = {"host": "0.0.0.0","port": 8000,"reload": True,"log_level": "info"}
uvicorn起動設定を別モジュールに持たせる
import uvicornfrom uvicorn_config import configif __name__ == "__main__":# uvicorn起動uvicorn.run("asgi:app",host=config["host"],port=config["port"],reload=config["reload"])
uvicorn.runメソッドの引数にuvicorn_configで設定した値を
渡してuvicornを起動する
再度コンテナを作成する
$ docker compose up -d$ docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES3fcab9cdd99d fastapi_uvicorn_start_pattern-uvicorn-start "python start_uvicor…" 44 seconds ago Up 38 seconds 0.0.0.0:8000->8000/tcp uvicorn-start
コンテナ作成後、コンテナのログを見ると
$ docker logs uvicorn-startINFO: Will watch for changes in these directories: ['/workspace']INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)INFO: Started reloader process [1] using WatchFilesINFO: Started server process [8]INFO: Waiting for application startup.INFO: Application startup complete.
コンテナ起動と同時にuvicornも動いてる
$ curl -i -X GET http://localhost:8000HTTP/1.1 211date: Mon, 24 Feb 2025 13:08:30 GMTserver: uvicorncontent-length: 168content-type: application/json[{"user_id":"1","name":"Tujimura","age":11},{"user_id":"2","name":"mori","age":20},{"user_id":"3","name":"shimada","age":501},{"user_id":"4","name":"kyogoku","age":70}]
fastapiアプリを動かす際によく使うuvicornサーバーの起動方法について
まとめてみた。
ケースバイケースだが、開発中はコマンライン起動で使うことが多い気がする。