Dockerコンテナ内のFastAPIのコードをVS Codeでデバッグする
はじめに
Dockerコンテナで動作するFastAPIのコードを以下のようにVSCodeでデバッグ(変数の状態を確認したり、ステップ実行したり)するための方法を記載します。
DjangoやFlaskでも同様の方法でデバッグの設定を行うことができると思います。
コンテナ側の設定
requirementsファイルにdebugpyを追加
debugpy
dockerfile内でdebugpyで起動するように設定
CMD ["python3", "-m", "debugpy", "--listen", "0.0.0.0:5678", "-m", "uvicorn", "app.main:app", "--reload", "--host", "0.0.0.0"]
例えば以下のようなステージにしておくと簡単に切り替えやすい
※ 検証用に色々余計なパッケージを入れているので、適宜読み替えてください
##################################################
# build image
##################################################
FROM python:3.11-slim-bookworm as builder
RUN apt-get update && \
apt-get install -y libmariadb-dev gcc default-mysql-client build-essential vim gettext
ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE=1
WORKDIR /src
##################################################
# local image
##################################################
FROM builder as local
COPY ./src/requirements /src/requirements
RUN pip install --upgrade pip && \
pip install --no-cache-dir --upgrade -r requirements/base.txt
COPY ./src /src
CMD [ "uvicorn", "app.main:app", "--host", "0.0.0.0", "--reload" ]
##################################################
# debug image
##################################################
FROM local as debug
CMD ["python3", "-m", "debugpy", "--listen", "0.0.0.0:5678", "-m", "uvicorn", "app.main:app", "--reload", "--host", "0.0.0.0"]
デバッグ用のdocker-composeファイルを作成
例えば以下のようなサービスを持つ、docker-compose.debug.yamlを作成する
version: "3.8"
services:
api:
build:
context: .
dockerfile: ./containers/api/Dockerfile
target: debug
depends_on:
- mysql
volumes:
- ./src:/src
env_file:
- ./.env
ports:
- "8006:8000"
- "5678:5678"
tty: true
ターゲットはdebug用ステージを指定する
target: debug
debugpyで待ち受けているポートをマッピングさせる
ports:
- "8006:8000"
- "5678:5678"
VSCode側の設定
プロジェクトルート配下にある.vscode
の中にlaunch.json
を作成する
{
// IntelliSense を使用して利用可能な属性を学べます。
// 既存の属性の説明をホバーして表示します。
// 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: FastAPI Container Debug",
"type": "python",
"request": "attach",
"connect": {
"host": "localhost",
"port": 5678
},
"pathMappings": [
{
"localRoot": "${workspaceFolder}/src/app",
"remoteRoot": "app"
}
],
"justMyCode": true
}
]
}
未作成の場合、launch.jsonを作成します。という部分から雛形を作ることができる
pathMappingはプロジェクトのディレクトリ構成に合わせる
私の環境では以下のディレクトリ構成になっているため、プロジェクト側は${workspaceFolder}/src/app
├── docker-compose.debug.yaml
├── docker-compose.yaml
├── src
│ ├── app
コンテナ側のWORKDIRはsrc/
なので、app
をマッピングしている。
debugを起動
コンテナをデバッグモードで起動する
docker-compose -f docker-compose.debug.yaml up -d --build
launch.jsonを読み取ってデバッグの起動ができるようになっているはずなので、起動する
起動すると、以下のような画面になる
ソースコードにブレイクポイントを設定し、APIを叩いてみると、処理が一時停止し、デバッグのプレビューが確認できる
devcontainersを使用したい場合
docker-compose.debug.yamlで.vscodeフォルダ以下をワークディレクトリ配下にマウントする
version: "3.8"
services:
api:
build:
context: .
dockerfile: ./containers/api/Dockerfile
target: debug
depends_on:
- mysql
volumes:
- ./src:/src
- ./.vscode:/src/.vscode
devcontainer.jsonを作成する
debug用と分けたい場合は下記のようなフォルダ構成にすると良さそう
├── .devcontainer
│ ├── debug
│ │ └── devcontainer.json
│ └── local
│ └── devcontainer.json
├── docker-compose.debug.yaml
├── docker-compose.yaml
devcontaier.jsonの例
{
"name": "fastapi-sample",
"dockerComposeFile": ["../../docker-compose.debug.yaml"],
"service": "api",
"workspaceFolder": "/src",
"settings":{
// mypy
"python.linting.pylintArgs": [
"--disable", "E1101,E0213,R0201",
"--extension-pkg-whitelist", "pydantic"
],
"python.pythonPath": "/usr/local/bin/python",
// format settings
"[python]": {
"editor.formatOnSave": true
},
// lint,mypy settings
"python.linting.mypyEnabled": true,
"python.linting.enabled": true,
"python.linting.mypyPath": "/usr/local/bin/mypy",
"python.linting.mypyArgs": ["--config=${containerWorkspaceFolder}/mypy.ini"],
"python.analysis.typeCheckingMode": "strict",
"python.analysis.diagnosticSeverityOverrides": {
"reportUnusedImport": "none",
"reportMissingTypeStubs": "none",
"reportUnknownParameterType": "none",
"reportUnknownMemberType": "none",
"reportUnknownArgumentType": "none",
"reportUnknownVariableType": "none",
"reportUntypedBaseClass" : "none"
}
},
"extensions": [
"ms-python.python",
"njpwerner.autodocstring",
"mosapride.zenkaku",
"ms-python.vscode-pylance",
"ms-python.black-formatter"
]
}
devcontainerで開く
ビルドが必要な場合は
remote-containers.rebuildAndReopenInContainer
devcontainer.jsonファイルを選択できるので、debug用を選択する
ブレイクポイントを設定し、APIを叩くと、devcontainer内でもデバッグできることが確認できる
VSCodeでデバッグするデメリット
ソースコードを編集したときの開発サーバのreloadやアプリケーションの実行が重くなる気がします。そのため、デバッグの必要がない場合は、デバッグを含まない構成で起動した方が良いと思いました。
Discussion