実現したこと
クリックで、
フロントエンド、バックエンド、DBのコンテナが起動。
ブラウザからエンドポイントへリクエストを送り、ブレークポイントを置いたコードで停止して変数などを確認できる。
デバッグ環境構築前の構成
以下のようにフロントエンド、バックエンド、DBサーバー用のファイルをディレクトリで分けて、それぞれのDockerfileでフロントエンド、バックエンド、DBそれぞれのコンテナを構成し、qaapp配下のdocker-compose.ymlファイルでdocker-composeによるコンテナの起動を構成していました
バックエンドではフレームワークとしてFastAPIを採用していて、今回はバックエンドに対してデバッグ環境を構築しました。
参考までに、作成しようとしていたものは、qaappというディレクトリ名からも察せられるかもしれませんが、自分で作った問題と答えを投稿できる一問一答管理システムです。
qaapp/
├─ frontend/
│ │ ︙
│ └ Dockerfile
├─ backend/
│ │ ︙
│ └ Dockerfile
├─ db/
│ │ ︙
│ └ Dockerfile
└─ docker-compose.yml
services:
db:
container_name: qaapp_db
build:
context: ./db
ports:
- 13306:3306
command: --default-authentication-plugin=mysql_native_password
networks:
- qaapp
frontend:
container_name: qaapp_frontend
build:
context: ./frontend
ports:
- 8080:80
networks:
- qaapp
backend:
container_name: qaapp_backend
build:
context: .
dockerfile: ./backend/Dockerfile
volumes:
- type: bind
source: ./backend/src
target: /app/src
- type: bind
source: ./backend/main.py
target: /app/main.py
tty: true
ports:
- 8090:80
networks:
- qaapp
networks:
qaapp:
driver: bridge
FROM ubuntu:jammy
RUN mkdir app && mkdir app/src
COPY ./backend/Pipfile.lock app
COPY ./backend/run.sh app
RUN apt-get -y update \
&& apt -y update\
&& apt -y install curl \
&& apt-get -y install python3 python3-pip\
&& pip3 install pipenv
RUN cd app && pipenv sync
EXPOSE 80
EXPOSE 8040
CMD cd app && pipenv run uvicorn main:app --host 0.0.0.0 --port 80 --reload
モチベーション
開発途中で効率を上げるためにデバッグを実施したくなりました。
すでにdocker-composeとDockerfileによるコンテナの作成を完了していたので、これらのコンテナに対してattachしてデバッグできるようにすることを目指そうと考えました。
大まかな構成
-
.vscode/tasks.json
でdocker-compose run
を実行するtaskを作成 -
.vscode/launch.json
でpreLaunchTask
で1で作成したtaskを指定ししたデバッグ実行設定を作成 - dubugモードでバックエンドアプリケーションを実行するdocker-composeファイルを作成
以下でそれぞれの手順について説明します。
.vscode/tasks.jsonでdocker-compose runを実行するtaskを作成
{
"version": "2.0.0",
"tasks": [
{
"label": "run qaapp",
"type": "docker-compose",
"dockerCompose": {
"up": {
"detached": true,
"build": false,
},
"files": [
"${workspaceFolder}/docker-compose.local.debug.yml"
]
}
}
]
}
filesプロパティで手順3で作成するデバッグ用のdocker-composeファイル(docker-compose.local.debug.yml)を指定しています。
.vscode/launch.jsonでpreLaunchTaskで1で作成したtaskを指定ししたデバッグ実行設定を作成
{
"configurations": [
{
"request": "attach",
"type": "python",
"name": "Attach qaapp backend",
"preLaunchTask": "run qaapp",
"connect": {
"port": 8040,
"host": "localhost"
},
"pathMappings": [
{
"localRoot": "${workspaceFolder}/backend/",
"remoteRoot": "/app/"
}
],
"justMyCode": false
}
]
}
connect.portがデバッグでattachするためのportです。こちらのportはもともと開放していなかったので、テウン3でデバッグ用のdocker-composeファイル(docker-compose.local.debug.yml)`にこのportを開く設定を追加します。
dubugモードでバックエンドアプリケーションを実行するdocker-composeファイルを作成
services:
db:
container_name: qaapp_db
build:
context: ./db
ports:
- 13306:3306
command: --default-authentication-plugin=mysql_native_password
networks:
- qaapp
frontend:
container_name: qaapp_frontend
build:
context: ./frontend
ports:
- 8080:80
networks:
- qaapp
backend:
container_name: qaapp_backend
build:
context: .
dockerfile: ./backend/Dockerfile
volumes:
- type: bind
source: ./backend/src
target: /app/src
- type: bind
source: ./backend/main.py
target: /app/main.py
tty: true
ports:
- 8090:80
+ - 8040:8040
networks:
- qaapp
+ command: [
+ "sh",
+ "-c",
+ "cd app && pipenv install debugpy && pipenv run python -m debugpy --wait-for-client --listen 0.0.0.0:8040 -m uvicorn main:app --reload --host 0.0.0.0 --port 80"
+ ]
networks:
qaapp:
driver: bridge
もともとのdocker-composeファイルとの差分で表示しています。
追加したのは手順2の説明で触れたデバッグのためのport開放設定と、デバッグモードでattachを待ち受ける設定でバックエンドアプリケーションを実行するようにDockerfileのCMDを上書きする設定を追加しています。
pipenv run python -m debugpy --wait-for-client --listen 0.0.0.0:8040 -m uvicorn main:app --reload --host 0.0.0.0 --port 80
上のコマンドがポイントです。
参考文献
[vscodeのドキュメント]
https://code.visualstudio.com/docs/containers/reference
tasks.jsonでdocker-compose upする方法を知るために使用
https://code.visualstudio.com/docs/containers/debug-python
vscodeでpythonデバッグを実施するための基本を知るために使用
https://code.visualstudio.com/docs/containers/debug-common
launch.jsonで指定できる各種プロパティの意味を知るために使用
https://qiita.com/kaitolucifer/items/dc58efebd72d72a8feb2
pythonデバッグの基本を知るために使用
https://github.com/tiangolo/fastapi/issues/707
クリティカルなissueがFastAPIのリポジトリに上がっていて、最も参考になった