当サイトは、アフィリエイト広告を利用しています
Pythonではデバッグを行う場合
を使って実行するのが第一選択肢になる。
そしてPythonの「debugpy」を使ったデバッグ構成パターンは
Python実行場所├─ ローカル│ └─ デバッグ操作位置:同一環境│ ├─ デバッグ方式:launch│ └─ デバッグ方式:attach│ ├─ debugpy起動形態:埋め込み(import debugpy)│ └─ debugpy起動形態:外部起動(python -m debugpy)│└─ コンテナ├─ デバッグ操作位置:同一環境(コンテナに入る)│ ├─ デバッグ方式:launch│ └─ デバッグ方式:attach│ ├─ debugpy起動形態:埋め込み│ └─ debugpy起動形態:外部起動│└─ デバッグ操作位置:別環境(ホストから接続)└─ デバッグ方式:attach├─ debugpy起動形態:埋め込み└─ debugpy起動形態:外部起動
がある。
詳しくは下記記事参照。
当記事ではこの構成パターンのうちの
について実装サンプルを使って解説する。
コンテナ × 別環境デバッグとは
するデバッグ構成のこと。
ここでいう別環境とは
が異なるという意味。
つまり
ホストOS└─ VS CodeDockerコンテナ├─ Python└─ debugpy
という構成になる。
同一環境デバッグではVS Code自体をコンテナへアタッチしていたが、別環境デバッグではVS CodeはホストOS上で動作する。
VS Codeからコンテナ内のdebugpyへネットワーク経由で接続することでデバッグを行う。
コンテナ × 別環境デバッグは
といった特徴がある。
実際の開発では
という構成が非常に多い。
例えば
などでは
docker compose up
でアプリを起動し、
後からVS Codeでattachしてデバッグするケースが多い。
そのため実務では
が最も利用頻度の高いデバッグ構成になる。
コンテナ × 別環境では以下の2パターンが存在する。
launchは利用できない。
なぜならVS CodeとPythonが別環境だからである。
VS Codeはコンテナ内のPythonプロセスを直接起動できない。
そのため
コンテナ上でPython起動↓debugpy待受↓ローカルからVS Codeがattach↓デバッグ開始
という流れになる。
今回の構成は以下。
|-- .vscode| `-- launch.json|-- Dockerfile|-- docker-compose.yml|-- main.py`-- requirements.txt
debugpy
attachではPython側でdebugpyを起動する必要があるため必要。
# 軽量&最新系に更新(2026時点で安定して使いやすい)FROM python:3.12-slim# pipを最新化 + キャッシュ削減RUN python -m pip install --upgrade pip && \pip install --no-cache-dir --upgrade setuptools wheel# 作業ディレクトリWORKDIR /app# 依存関係を先にコピー(レイヤーキャッシュ最適化)COPY requirements.txt .# パッケージインストール(キャッシュ無効)RUN pip install --no-cache-dir -r requirements.txt
version: "3"services:container_python_remote_debug:container_name: "container_python_remote_debug"# Dockerfileをビルドbuild:context: .dockerfile: Dockerfiletty: true# プロジェクトをバインドマウントvolumes:- .:/appports:- "5678:5678"
重要なのは
ports:- "5678:5678"
である。
ホストOS上のVS Codeからコンテナ内debugpyへ接続するため、
debugpy待受ポートを公開する必要がある。
ホストのVS Code↓ localhost:5678Docker Port Mapping↓debugpy
という経路で接続される。
attachは既に動いているPythonプロセスに後からデバッガを接続する方式。
コンテナ × 別環境ではattachしか利用できない。
そしてattachではdebugpyの起動形態が
の2種類あるので、パターン別に実装して動作を確認する。
「debugpy起動形態:埋め込み」はdebugpyをPythonプロセスへ埋め込む方式。
VS Code(ホストOS)↓localhost:5678↓Docker Port Mapping↓debugpy埋め込み済みPython↓デバッグ開始
のようになるイメージ。
launchデバッグとは異なり、VS CodeがPythonをdebugpy付きで実行してくれるわけではない。
debugpy埋め込み済みのPythonをコンテナ内で実行し、ホストOS上のVS Codeからattachしてデバッグを開始する。
作成するファイルは
で構成は
|-- .vscode| `-- launch.json`-- main.py
になる。
import debugpy# コンテナ外から接続できるようにするdebugpy.listen(("0.0.0.0", 5678))# VS Codeから接続されるまで待機debugpy.wait_for_client()def main():print("hello1")print("hello2")print("hello3")print("hello4")print("hello5")if __name__ == "__main__":main()
ポイントは
debugpy.listen(("0.0.0.0", 5678))
である。
同一環境デバッグでは
debugpy.listen(5678)
でも動作するが、
別環境デバッグではコンテナ外から接続するため
どこからの通信もうけつける
0.0.0.0
で待ち受ける必要がある。
また
debugpy.wait_for_client()
によってVS Codeが接続するまで処理を停止できる。
{"version": "0.2.0","configurations": [{"name": "Python デバッガー: コンテナ attach","type": "debugpy","request": "attach","justMyCode": false,"connect": {"host": "localhost","port": 5678},"pathMappings": [{"localRoot": "${workspaceFolder}","remoteRoot": "/app"}]}]}
まずVScodeからコンテナにアタッチし、python実行する
$ docker exec -it container_python_remote_debug bashroot@cc7fb729bb77:/app# python main.py0.00s - Debugger warning: It seems that frozen modules are being used, which may0.00s - make the debugger miss breakpoints. Please pass -Xfrozen_modules=off0.00s - to python to disable frozen modules.0.00s - Note: Debugging will proceed. Set PYDEVD_DISABLE_FILE_VALIDATION=1 to disable this validation.
実行すると
debugpy.wait_for_client()
で停止する。
その後VS Codeからattachを実行するとデバッグが開始される。
「debugpy起動形態:外部起動」はdebugpyを実行コマンドで指定する方式。
コードへdebugpyを書き込まないため、
実務ではこちらの方が使われることが多い。
VS Code(ホストOS)↓localhost:5678↓Docker Port Mapping↓python -m debugpy↓main.py
のようになるイメージ。
こちらもlaunchデバッグとは異なり、VS CodeがPythonをdebugpy付きで実行してくれるわけではない。
Pythonを起動するコマンドでdebugpyを指定し、
その後VS Codeからattachしてデバッグを開始する。
作成するファイルは
で構成は
|-- .vscode| `-- launch.json`-- main.py
になる。
def main():print("hello1")print("hello2")print("hello3")print("hello4")print("hello5")if __name__ == "__main__":main()
debugpyはコマンドで起動するため、ソースコードには埋め込まない。
埋め込み方式と同じ。
{"version": "0.2.0","configurations": [{"name": "Python デバッガー: コンテナ attach","type": "debugpy","request": "attach","justMyCode": false,"connect": {"host": "localhost","port": 5678},"pathMappings": [{"localRoot": "${workspaceFolder}","remoteRoot": "/app"}]}]}
まずコンテナ内でPythonスクリプトをdebugpy付きで起動する。
$ docker exec -it container_python_remote_debug bashroot@c4a02a6eef54:/app#root@c4a02a6eef54:/app# python -m debugpy \--listen 0.0.0.0:5678 \--wait-for-client \main.py0.01s - Debugger warning: It seems that frozen modules are being used, which may0.00s - make the debugger miss breakpoints. Please pass -Xfrozen_modules=off0.00s - to python to disable frozen modules.0.00s - Note: Debugging will proceed. Set PYDEVD_DISABLE_FILE_VALIDATION=1 to disable this validation.
0.0.0.0 --wait-for-client を付ける その後VS Codeのattachデバッガを実行するとデバッグが開始される。
コンテナ × 別環境デバッグではpathMappingsが重要になる。
なぜなら
ホスト└─ project└─ main.pyコンテナ└─ /app└─ main.py
のように、VS CodeとPythonが参照しているパスが異なるためである。
VS Codeはホストの
を見ている。
一方でコンテナではPythonは
を実行している。
そのためdebugpyは
ホストのVS Code側のパス↓コンテナのPython側のパス
を対応付ける必要がある。
{"version": "0.2.0","configurations": [{"name": "Python デバッガー: コンテナ attach","type": "debugpy","request": "attach","connect": {"host": "localhost","port": 5678},"pathMappings": [{"localRoot": "${workspaceFolder}","remoteRoot": "/app"}]}]}
ここで
を表す
pathMappingsが正しく設定されていない場合、
といった問題が発生する。
特に
という場合は、まずpathMappingsを疑うとよい。
ここで実務上非常に重要な注意点がある。
pathMappingsを設定すると、
ように見える。
しかし実際にはそうではない。
今回の構成では
volumes:- .:/app
としている。
そのため
ホスト└─ project└─ main.pyコンテナ└─ /app└─ main.py
は対応付けできる。
つまり
は問題なくデバッグできる。
例えばDockerfileで
RUN pip install fastapi sqlalchemy pydantic
したとする。
するとライブラリは通常はコンテナ内の
/usr/local/lib/python3.12/site-packages/
などへ配置される。
つまり実際のコンテナは
Dockerコンテナ├─ /app│ └─ main.py│└─ /usr/local/lib/python3.12/site-packages├─ fastapi├─ sqlalchemy└─ pydantic
という構成になる。
しかしホスト側には
/usr/local/lib/python3.12/site-packages/fastapi
が存在しない。
※コンテナ起動時にインストールしているのでホスト側には存在しない
そのためVS Codeは
コンテナ側/usr/local/lib/python3.12/site-packages/fastapi↓ホスト側???
となり、ホスト:コンテナ間で対応付けできない場合がある。
この状況では
といった問題が発生することがある。
一方で
/app
配下の自作コードは問題なくデバッグできる。
そのため
という現象が発生する。
最も一般的。
{"justMyCode": true}
として、
のみを対象にする。
FastAPIやSQLAlchemyの内部まで追うことは少ない。
ライブラリ内部まで追いたい場合は、
ホスト側にも同じライブラリ環境を構築する。
python -m venv .venvpip install -r requirements.txt
として
ホスト└─ .venvコンテナ└─ site-packages
でバージョンを揃える。
この場合はVS Codeがライブラリソースを解決しやすくなる。
ライブラリ自体を開発している場合は
をホスト側へ配置し、
ボリュームマウントして利用する。
これはライブラリ開発時の特殊なケースであり、
通常のアプリケーション開発ではあまり行わない。
コンテナ × 別環境デバッグでは
わけではない。
pathMappingsで対応できるのは
だけである。
そのため実務では
として運用することが多い。
実務ではこちらの方が多い。
例えば以下のようにする。
version: "3"services:container_python_remote_debug:container_name: "container_python_remote_debug"# Dockerfileをビルドbuild:context: .dockerfile: Dockerfiletty: true# プロジェクトをバインドマウントvolumes:- .:/appports:- "5678:5678"command: >python -m debugpy--listen 0.0.0.0:5678--wait-for-clientmain.py
この場合は
docker compose up
だけでdebugpy付きのPythonプロセスが起動する。
その後、ホストOS上のVS Codeからattachする。
実務では起動方法を
へ集約した方が管理しやすい。
例えば
全員で同じ起動方法を共有できる。
そのため外部起動を利用する場合は、
docker-compose.ymlへ記述する構成が最も実務的である。
本質的な違いは
である。
Dockerコンテナ├─ VS Code├─ Python└─ debugpy
すべてコンテナ上で動く
ホストOS└─ VS CodeDockerコンテナ├─ Python└─ debugpy
ホストとコンテナの別々の環境で動作する
この違いにより、別環境では
が必要になる。
同一環境では
VS Code(コンテナ内)↓ localhostdebugpy(コンテナ内)
になる。
一方で別環境では
VS Code(ホスト)↓ localhost:5678Docker Port Mapping↓debugpy(コンテナ内)
になる。
つまり別環境ではネットワーク越しの接続が発生する。
コンテナ × 別環境では
が別環境で動作している。
そのため理解すべきポイントは次の4つ。
ports:- "5678:5678"
vscodeからアタッチするためのポートを開けておく
debugpy.listen(("0.0.0.0", 5678))
または
python -m debugpy \--listen 0.0.0.0:5678
「0.0.0.0」は全NICで待受する
"pathMappings": [{"localRoot": "${workspaceFolder}","remoteRoot": "/app"}]
ホストとコンテナの紐づけ
pathMappingsで解決できるのは
だけである。
site-packages問題は別で考える必要がある。
debugpy.wait_for_client()
を特定位置へ埋め込んで停止したい場合。
実務ではこちらの方が多い。
実務では
などで開発行う場合は
のどちらかが最も実用的な構成になる
当記事で紹介した構成
【コンテナ × 別環境 × attach × 外部起動】┌──────────────────────────────┐│ ホストPC ││ ││ VS Code ││ launch.json ││ request: attach ││ connect: localhost:5678 │└───────────────┬──────────────┘││ Docker port forward│ localhost:5678 → container:5678▼┌──────────────────────────────┐│ Dockerコンテナ ││ ││ Python / FastAPI / Flask ││ Django / バッチ処理 ││ ││ python -m debugpy ││ --listen 0.0.0.0:5678 ││ main.py │└──────────────────────────────┘
【コンテナ × 別環境 × attach × 外部起動】┌──────────────────────────────┐│ ホストPC ││ ││ VS Code ││ launch.json ││ request: attach ││ connect: localhost:5678 │└───────────────┬──────────────┘││ Docker port forward│ localhost:5678 → container:5678▼┌──────────────────────────────┐│ Dockerコンテナ ││ ││ Python / FastAPI / Flask ││ Django / バッチ処理 ││ ││ python -m debugpy ││ --listen 0.0.0.0:5678 ││ main.py │└──────────────────────────────┘
詳しくは下記