
FastAPI勉強日記: #2. Dockerコンテナの中のFastAPIのコードに対してデバッガを使う
前回、FastAPIをDockerコンテナでFastAPIを起動し、
ローカルマシン上のコードを編集すると、すぐにコンテナ内に修正が反映されてブラウザで確認できる、
というところまで開発環境を構築した。
後はコンテナ内のコードに対してデバッガをつかって処理を止めたり、ステップ実行ができればローカルマシーンの上で直接FastAPIを実行させて開発するのと遜色のない環境が揃うことになる。
今日はコンテナ内のFastAPIのコードに対してVSCodeデバッガを動かすところまでを目標に試行錯誤してみた。
Dockerfile
Dockerファイルを以下のように設定した。
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
# Note: In default, the working directory is /app in this base image.
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY ./app /app
CMD ["python3", "-m", "debugpy", "--listen", "0.0.0.0:5678", "-m", "uvicorn", "main:app", "--reload", "--host", "0.0.0.0", "--port", "8000"]
前回と違うところは、最後のコマンドだけ。
前回は、↓のようにuvicornを実行したが、
CMD ["uvicorn", "main:app", "--reload", "--host", "0.0.0.0", "--port", "3000"]
これを↓のように変えた。
CMD ["python3", "-m", "debugpy", "--listen", "0.0.0.0:5678", "-m", "uvicorn", "main:app", "--reload", "--host", "0.0.0.0", "--port", "8000"]
debugpyを実行し、debugpyを介してuvicornを実行するようなイメージ(だと思う。。、debugpyについては後でしっかり調べてみようと思う)
前回は3000番ポートをつかってFastAPIのリクエストを受け付けるようにしたが、いろいろ調べていて8000番ポートを使っていることが多いので、8000に変えました。(上のコマンドの最後の"--port", "8000"]の部分)
requirements.txt
debugpyモジュールを使うので、requirements.txtに下の一行を追加する。
debugpy
docker-compose.yml
前回と違うところは、コンテナの5678ポートを新たにホストマシンの5678番ポートにオープンにしたこと。
version: '3.7'
services:
api:
build: .
container_name: "api"
volumes:
- ./app:/app
ports:
- 8000:8000
- 5678:5678
コンテナの中ではdebugpyが5678番ポートでアクセスを受け付けるように動いていくれるので、これによってVSCodeのデバッガが実行中にコードをブレイクポイントでブレイクしたりステップ実行ができるようになるようだ。
launch.jsonの作成
VSCodeの「Run and Debug」アイコン(再生ボタンのようなアイコン)をクリックする。
画面上部にある「create a launch.json file」リンクからlaunch.jsonファイルを作成できる。
launch.jsonの中身は下のように設定した。
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: FastAPI Container Debug",
"type": "python",
"request": "attach",
"port": 5678,
"host": "localhost",
"pathMappings": [
{
"localRoot": "${workspaceFolder}/app",
"remoteRoot": "/app"
}
]
}
]
}
ハマりポイントは、localRootとremoteRoot。
localRootには自分のローカルマシーンのプロジェクトの中でmain.pyが入っているフォルダを指定し、
remoteRootには、Dockerコンテナの中でそのフォルダをコピーした先のフォルダを指定する。
Dockerfileの中で、ローカルマシーン -> コンテナにフォルダをコピーする以下のコマンドを書いたが、これと同じ場所が指定されていればOKとなる。
COPY ./app /app
もう1つ重要なことはportに5678が指定されていること↓
"port": 5678,
これによって、このlaunch.jsonを使ってデバッガを起動すると、5678番ポートを使って、コンテナの中のdebugpyとやり取りが始まる。
コンテナの起動
下のdocker-composeコマンドをつかって、Dockerイメージをビルドして、コンテナを起動する。
docker-compose up --build
(2回目以降は、Dockerfile, docker-compose.xmlを編集しないのであれば、--buildオプションは不要になる)
一旦ブラザでlocalhost:8000にアクセスして、コンテナ及びその中のFastAPIが動いているかを確認する。

ブレイクポイントを貼ってデバッガを起動
VSCodeを開き、app/main.pyを開いて、"/"(ルート)APIのハンドラにブレークポイントをはる。

その後、VSCodeのRun And Debugメニューを開いて、先程作ったlaunch.jsonの設定を指定して、デバッガを起動する。

ブラウザで、
localhost:8000/
を開き、"/" (ルート)APIを叩くと、下のようにプログラムの処理がブレークポイントのところで止まった!

これで、ローカルマシンを汚すことなく、コンテナ内で自分の好きな環境を作り、コードの編集 -> デバッガを使ってデバッグ
という自分にとって理想の開発環境を用意することができた。
ここで一旦燃料切れに。。
コーヒーを飲んで次はリクエストデータのバリデーションか、もしくはどのORMapperがいいかを調べてみたい。
続く。
このブログに関する質問や、Webサービス、Android・iOSアプリの開発の相談はこちら↓↓↓からお願いします!
mizutori@goldrushcomputing.com
@mizutory
次回は↓↓↓