コンテナ内でPythonをデバッグする
PythonプロジェクトにDockerファイルを追加すると、コンテナ内でアプリケーションをデバッグできるように、タスクと起動構成が追加されます。Pythonプロジェクトのさまざまなシナリオに対応するため、一部のアプリケーションでは追加の構成が必要になる場合があります。
コンテナのエントリーポイントを構成する
tasks.jsonでプロパティを設定することで、コンテナのエントリーポイントを構成できます。VS Codeは、初めてContainers: Add Docker Files to Workspace...コマンドを使用するときに、コンテナのエントリーポイントを自動的に構成します。
例: Pythonモジュールのエントリーポイントを構成する
{
"tasks": [
{
"type": "docker-run",
"label": "docker-run: debug",
"dependsOn": ["docker-build"],
"python": {
"module": "myapp"
}
}
]
}
例: Pythonファイルのエントリーポイントを構成する
{
"tasks": [
{
"type": "docker-run",
"label": "docker-run: debug",
"dependsOn": ["docker-build"],
"python": {
"args": ["runserver", "0.0.0.0:8000", "--nothreading", "--noreload"],
"file": "manage.py"
}
}
]
}
ブラウザをアプリケーションのエントリーページに自動的に起動する
Containers: Python - DjangoまたはContainers: Python - Flaskの起動構成を選択すると、ブラウザがアプリケーションのメインページに自動的に起動されます。この機能はデフォルトで有効になっていますが、launch.jsonでdockerServerReadyActionオブジェクトを設定することで、この動作を明示的に構成できます。
この機能はアプリケーションのいくつかの側面に依存します。
- アプリケーションはデバッグコンソールまたはDockerログに出力する必要があります。
- アプリケーションは「server ready」メッセージをログに出力する必要があります。
- アプリケーションはブラウズ可能なページを提供する必要があります。
特定のサーバーメッセージパターンに基づいて、about.htmlページを開くようにブラウザを起動するためにdockerServerReadyActionを使用する例を次に示します。
{
"configurations": [
{
"name": "Containers: Python - Django",
"type": "docker",
"request": "launch",
"preLaunchTask": "docker-run: debug",
"python": {
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "/app"
}
],
"projectType": "django"
},
"dockerServerReadyAction": {
"action": "openExternally",
"pattern": "Starting development server at (https?://\\S+|[0-9]+)",
"uriFormat": "%s://:%s/about.html"
}
}
]
}
注:
pattern属性にある正規表現は、単に「Starting development server athttps://:8000」のようなログメッセージをキャプチャしようとします。これは、httpまたはhttpsのURL、任意のホスト名、および任意のポートのバリエーションに対応しています。
重要なdockerServerReadyActionオブジェクトプロパティ
-
action: パターンが見つかったときに実行するアクション。debugWithChromeまたはopenExternallyのいずれかです。 -
pattern: アプリケーションが上記とは異なるメッセージをログに記録する場合、dockerServerReadyActionオブジェクトのpatternプロパティを、そのメッセージに一致するJavaScript正規表現に設定します。正規表現には、アプリケーションがリッスンしているポートに対応するキャプチャグループを含める必要があります。 -
uriFormat: デフォルトでは、コンテナツール拡張機能はブラウザのメインページを開きます(これはアプリケーションによって決定されます)。上記の例のように、ブラウザに特定のページを開かせたい場合は、dockerServerReadyActionオブジェクトのuriFormatプロパティを、プロトコルとポートの置換を示す2つの文字列トークンを含むフォーマット文字列に設定する必要があります。
DjangoまたはFlaskアプリでホットリロードを有効にする方法
DjangoまたはFlaskでContainers: Add Docker Files to Workspaceを選択すると、静的デプロイ用に構成されたDockerfileとtasks.jsonが提供されます。アプリのコードを変更するたびに、コンテナを再構築して再実行する必要があります。ホットリロードを使用すると、コンテナが実行を継続しながら、アプリのコードの変更を視覚化できます。これらの手順でホットリロードを有効にします。
Djangoアプリの場合
-
Dockerfileで、アプリのコードをコンテナに追加する行をコメントアウトします。
#ADD . /app -
tasks.jsonファイルのdocker-runタスク内で、volumesプロパティを持つ新しいdockerRun属性を作成します。この設定により、現在のワークスペースフォルダ(アプリのコード)からコンテナ内の/appフォルダへのマッピングが作成されます。{ "type": "docker-run", "label": "docker-run: debug", "dependsOn": [ "docker-build" ], "dockerRun": { "volumes": [ { "containerPath": "/app", "localPath": "${workspaceFolder}" } ] }, ... } -
python属性を編集し、
--noreloadと--nothreadingを削除します。{ ... "dockerRun": { "volumes": [ { "containerPath": "/app", "localPath": "${workspaceFolder}" } ] }, "python": { "args": [ "runserver", "0.0.0.0:8000", ], "file": "manage.py" } } -
Containers: Python – Django起動構成を選択し、F5を押してコンテナをビルドして実行します。
-
任意のファイルを変更して保存します。
-
ブラウザを更新し、変更が適用されたことを確認します。
Flaskアプリの場合
-
Dockerfileで、アプリのコードをコンテナに追加する行をコメントアウトします。
#ADD . /app -
tasks.jsonファイルのdocker-runタスク内で、既存のdockerRun属性を編集し、envプロパティにFLASK_ENVを追加し、volumesプロパティも追加します。この設定により、現在のワークスペースフォルダ(アプリのコード)からコンテナ内の/appフォルダへのマッピングが作成されます。{ "type": "docker-run", "label": "docker-run: debug", "dependsOn": [ "docker-build" ], "dockerRun": { "env": { "FLASK_APP": "path_to/flask_entry_point.py", "FLASK_ENV": "development" }, "volumes": [ { "containerPath": "/app", "localPath": "${workspaceFolder}" } ] }, ... } -
python属性を編集し、
--no-reloadと--no-debuggerを削除します。{ ... "dockerRun": { "env": { "FLASK_APP": "path_to/flask_entry_point.py", "FLASK_ENV": "development" }, "volumes": [ { "containerPath": "/app", "localPath": "${workspaceFolder}" } ] }, "python": { "args": [ "run", "--host", "0.0.0.0", "--port", "5000" ], "module": "flask" } } -
Containers: Python – Flask起動構成を選択し、F5を押してコンテナをビルドして実行します。
-
任意のファイルを変更して保存します。
-
ブラウザを更新し、変更が適用されたことを確認します。
コンテナをまとめてビルドして実行する方法
- 前述の
tasks.jsonファイルには、docker-buildタスクへの依存関係があります。このタスクは、tasks.jsonのtasks配列の一部です。例:
"tasks":
[
{
...
},
{
"label": "docker-build",
"type": "docker-build",
"dockerBuild": {
"context": "${workspaceFolder}",
"dockerfile": "${workspaceFolder}/Dockerfile",
"tag": "YOUR_IMAGE_NAME:YOUR_IMAGE_TAG"
}
}
]
ヒント: 依存関係がdocker-buildを明確に指定しているため、名前はこのタスクと一致する必要があります。必要に応じて名前を変更できます。
-
JSON内の
dockerBuildオブジェクトは、以下のパラメーターを許可します。- context: Dockerfileが呼び出されるビルドコンテキスト
- dockerfile: 実行するDockerfileへのパス
- tag: ビルドするイメージの名前とバージョンタグ
-
全体として、FlaskアプリケーションをビルドおよびデバッグするためのVS Codeセットアップは次のようになります。
-
launch.json{ "version": "0.2.0", "configurations": [ { "name": "Debug Flask App", "type": "docker", "request": "launch", "preLaunchTask": "docker-run: debug", "python": { "pathMappings": [ { "localRoot": "${workspaceFolder}", "remoteRoot": "/app" } ], "projectType": "flask" }, "dockerServerReadyAction": { "action": "openExternally", "pattern": "Running on (http?://\\S+|[0-9]+)", "uriFormat": "%s://:%s/" } } ] } -
tasks.json{ "version": "2.0.0", "tasks": [ { "type": "docker-run", "label": "docker-run: debug", "dependsOn": ["docker-build"], "dockerRun": { "containerName": "YOUR_IMAGE_NAME", "image": "YOUR_IMAGE_NAME:YOUR_IMAGE_TAG", "env": { "FLASK_APP": "path_to/flask_entry_point.py", "FLASK_ENV": "development" }, "volumes": [ { "containerPath": "/app", "localPath": "${workspaceFolder}" } ], "ports": [ { "containerPort": 5000, "hostPort": 5000 } ] }, "python": { "args": ["run", "--host", "0.0.0.0", "--port", "5000"], "module": "flask" } }, { "label": "docker-build", "type": "docker-build", "dockerBuild": { "context": "${workspaceFolder}", "dockerfile": "${workspaceFolder}/Dockerfile", "tag": "YOUR_IMAGE_NAME:YOUR_IMAGE_TAG" } } ] }
-
次のステップ
詳細はこちら