当サイトは、アフィリエイト広告を利用しています

【Python×VSCode】Dockerコンテナ内Pythonをリモートデバッグする方法

作成日:2026月06月13日
更新日:2026年06月13日

Pythonではデバッグを行う場合

  • debugpy

を使って実行するのが第一選択肢になる。

そしてPythonの「debugpy」を使ったデバッグ構成パターンは

実用的なデバッグ構成パターン
Python実行場所
├─ ローカル
│ └─ デバッグ操作位置:同一環境
│ ├─ デバッグ方式:launch
│ └─ デバッグ方式:attach
│ ├─ debugpy起動形態:埋め込み(import debugpy)
│ └─ debugpy起動形態:外部起動(python -m debugpy)
└─ コンテナ
├─ デバッグ操作位置:同一環境(コンテナに入る)
│ ├─ デバッグ方式:launch
│ └─ デバッグ方式:attach
│ ├─ debugpy起動形態:埋め込み
│ └─ debugpy起動形態:外部起動
└─ デバッグ操作位置:別環境(ホストから接続)
└─ デバッグ方式:attach
├─ debugpy起動形態:埋め込み
└─ debugpy起動形態:外部起動

がある。

詳しくは下記記事参照。

当記事ではこの構成パターンのうちの

  • Pythonをコンテナでデバッグするパターン
  • コンテナ × 別環境
  • attach
  • debugpy埋め込み
  • debugpy外部起動

について実装サンプルを使って解説する。

コンテナ × 別環境デバッグとは何か?

コンテナ × 別環境デバッグとは

  • VS CodeはホストOS上で動作
  • PythonはDockerコンテナ内で動作

するデバッグ構成のこと。

ここでいう別環境とは

  • VS Codeの操作位置
  • Pythonの実行位置

が異なるという意味。

つまり

コンテナ×別環境
ホストOS
└─ VS Code
Dockerコンテナ
├─ Python
└─ debugpy

という構成になる。

同一環境デバッグではVS Code自体をコンテナへアタッチしていたが、別環境デバッグではVS CodeはホストOS上で動作する。

VS Codeからコンテナ内のdebugpyへネットワーク経由で接続することでデバッグを行う。

コンテナ × 別環境デバッグの特徴

コンテナ × 別環境デバッグは

  • VS CodeはホストOS
  • PythonはDockerコンテナ
  • コンテナへVS Codeをアタッチする必要がない
  • ローカル環境のVS Codeをそのまま利用できる
  • debugpy用ポート公開が必要
  • pathMappingsが必須

といった特徴がある。

コンテナ × 別環境デバッグの使いどころ

実際の開発では

  • Docker Composeでアプリを起動する
  • VS CodeはホストOSで利用する

という構成が非常に多い。

例えば

  • FastAPI
  • Flask
  • Django
  • Celery
  • バッチサーバ

などでは

コンテナ起動
docker compose up

でアプリを起動し、
後からVS Codeでattachしてデバッグするケースが多い。

そのため実務では

  • コンテナ × 別環境 × attach

が最も利用頻度の高いデバッグ構成になる。

デバッグ構成の全体像

コンテナ × 別環境では以下の2パターンが存在する。

  • attach × 埋め込み
  • attach × 外部起動

launchは利用できない。

なぜならVS CodeとPythonが別環境だからである。
VS Codeはコンテナ内のPythonプロセスを直接起動できない。

そのため

全体構成
コンテナ上でPython起動
debugpy待受
ローカルからVS Codeがattach
デバッグ開始

という流れになる。

前提構成

今回の構成は以下。

構成
|-- .vscode
| `-- launch.json
|-- Dockerfile
|-- docker-compose.yml
|-- main.py
`-- requirements.txt

requirements.txt

requirements.txt
debugpy

attachではPython側でdebugpyを起動する必要があるため必要。

Dockerfile

Dockerfile
# 軽量&最新系に更新(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

docker-compose.yml

docker-compose.yml
version: "3"
services:
container_python_remote_debug:
container_name: "container_python_remote_debug"
# Dockerfileをビルド
build:
context: .
dockerfile: Dockerfile
tty: true
# プロジェクトをバインドマウント
volumes:
- .:/app
ports:
- "5678:5678"

重要なのは

docker-compose.yml
ports:
- "5678:5678"

である。

ホストOS上のVS Codeからコンテナ内debugpyへ接続するため、
debugpy待受ポートを公開する必要がある。

debugpy接続
ホストのVS Code
↓ localhost:5678
Docker Port Mapping
debugpy

という経路で接続される。

attachデバッグ

attachは既に動いているPythonプロセスに後からデバッガを接続する方式。

コンテナ × 別環境ではattachしか利用できない。

そしてattachではdebugpyの起動形態が

  • 埋め込み
  • 外部起動

の2種類あるので、パターン別に実装して動作を確認する。

attachデバッグ:debugpy起動形態:埋め込み(import debugpy)

「debugpy起動形態:埋め込み」はdebugpyをPythonプロセスへ埋め込む方式。

仕組み

仕組み
VS Code(ホストOS)
localhost:5678
Docker Port Mapping
debugpy埋め込み済みPython
デバッグ開始

のようになるイメージ。

launchデバッグとは異なり、VS CodeがPythonをdebugpy付きで実行してくれるわけではない。
debugpy埋め込み済みのPythonをコンテナ内で実行し、ホストOS上のVS Codeからattachしてデバッグを開始する。

attachデバッグ:debugpy起動形態:埋め込み実装例

作成するファイルは

  • launch.json
  • main.py

で構成は

構成
|-- .vscode
| `-- launch.json
`-- main.py

になる。

main.py

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
debugpy.listen(5678)

でも動作するが、

別環境デバッグではコンテナ外から接続するため
どこからの通信もうけつける

待ち受け
0.0.0.0

で待ち受ける必要がある。

また

main.py
debugpy.wait_for_client()

によってVS Codeが接続するまで処理を停止できる。

.vscode/launch.json

launch.json
{
"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実行する

bash
$ docker exec -it container_python_remote_debug bash
root@cc7fb729bb77:/app# python main.py
0.00s - Debugger warning: It seems that frozen modules are being used, which may
0.00s - make the debugger miss breakpoints. Please pass -Xfrozen_modules=off
0.00s - to python to disable frozen modules.
0.00s - Note: Debugging will proceed. Set PYDEVD_DISABLE_FILE_VALIDATION=1 to disable this validation.

実行すると

python
debugpy.wait_for_client()

で停止する。

その後VS Codeからattachを実行するとデバッグが開始される。
2026-06-13-13-56-32

attachデバッグ:debugpy起動形態:外部起動(python -m debugpy)

「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してデバッグを開始する。

attachデバッグ:debugpy起動形態:外部起動実装例

作成するファイルは

  • launch.json
  • main.py

で構成は

構成
|-- .vscode
| `-- launch.json
`-- main.py

になる。

main.py

main.py
def main():
print("hello1")
print("hello2")
print("hello3")
print("hello4")
print("hello5")
if __name__ == "__main__":
main()

debugpyはコマンドで起動するため、ソースコードには埋め込まない。

.vscode/launch.json

埋め込み方式と同じ。

launch.json
{
"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 bash
root@c4a02a6eef54:/app#
root@c4a02a6eef54:/app# python -m debugpy \
--listen 0.0.0.0:5678 \
--wait-for-client \
main.py
0.01s - Debugger warning: It seems that frozen modules are being used, which may
0.00s - make the debugger miss breakpoints. Please pass -Xfrozen_modules=off
0.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デバッガを実行するとデバッグが開始される。
2026-06-13-14-12-28

pathMappingsについて

コンテナ × 別環境デバッグではpathMappingsが重要になる。

なぜなら

環境比較
ホスト
└─ project
└─ main.py
コンテナ
└─ /app
└─ main.py

のように、VS CodeとPythonが参照しているパスが異なるためである。

VS Codeはホストの

  • C:\project\main.py
  • /Users/user/project/main.py

を見ている。

一方でコンテナではPythonは

  • /app/main.py

を実行している。

そのためdebugpyは

環境紐づけ
ホストのVS Code側のパス
コンテナのPython側のパス

を対応付ける必要がある。

pathMappings設定例

pathMappings設定例
{
"version": "0.2.0",
"configurations": [
{
"name": "Python デバッガー: コンテナ attach",
"type": "debugpy",
"request": "attach",
"connect": {
"host": "localhost",
"port": 5678
},
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "/app"
}
]
}
]
}

ここで

  • localRoot:VSCode側(ホスト)のプロジェクトルート
  • remoteRoot:コンテナ内のプロジェクトルート。

を表す

pathMappingsがないとどうなるか

pathMappingsが正しく設定されていない場合、

  • ブレークポイントがグレーになる
  • ブレークポイントで停止しない
  • ソースコードが見つからない
  • 別ファイルとして開かれる

といった問題が発生する。

特に

  • ブレークポイントを置いたのに止まらない

という場合は、まずpathMappingsを疑うとよい。

コンテナ内だけに存在するライブラリについて

ここで実務上非常に重要な注意点がある。

pathMappingsを設定すると、

  • コンテナ内のすべてのコードを自由にデバッグできる

ように見える。
しかし実際にはそうではない。

pathMappingsで対応できるのはホスト側にも存在するコード

今回の構成では

docker-compose.yml
volumes:
- .:/app

としている。

そのため

環境比較
ホスト
└─ project
└─ main.py
コンテナ
└─ /app
└─ main.py

は対応付けできる。

つまり

  • 自作コード
  • アプリケーションコード

は問題なくデバッグできる。

コンテナ内でインストールされたライブラリは別問題

例えばDockerfileで

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
ホスト側
???

となり、ホスト:コンテナ間で対応付けできない場合がある。

発生しやすい問題

この状況では

  • FastAPI内部へブレークポイントを置けない
  • SQLAlchemy内部へステップインできない
  • ソースコードが見つからない
  • 別ファイルとして開かれる
  • Disassembly表示になる

といった問題が発生することがある。

一方で

自作コードパス
/app

配下の自作コードは問題なくデバッグできる。

そのため

  • 自作コード → ブレークポイントで止まる
  • FastAPI内部 → ブレークポイントで止まらない

という現象が発生する。

実務ではどうするか

パターン1:自作コードだけデバッグする

最も一般的。

launch.json
{
"justMyCode": true
}

として、

  • 自作コード
  • 業務ロジック

のみを対象にする。
FastAPIやSQLAlchemyの内部まで追うことは少ない。

パターン2:ホスト側にも同じ環境を作る

ライブラリ内部まで追いたい場合は、
ホスト側にも同じライブラリ環境を構築する。

Dockerfile
python -m venv .venv
pip install -r requirements.txt

として

環境比較
ホスト
└─ .venv
コンテナ
└─ site-packages

でバージョンを揃える。

この場合はVS Codeがライブラリソースを解決しやすくなる。

パターン3:ライブラリ開発を行う

ライブラリ自体を開発している場合は

  • FastAPI本体
  • SQLAlchemy本体
  • 自作ライブラリ

をホスト側へ配置し、

ボリュームマウントして利用する。
これはライブラリ開発時の特殊なケースであり、
通常のアプリケーション開発ではあまり行わない。

実務上の考え方

コンテナ × 別環境デバッグでは

  • pathMappingsがあれば何でもデバッグできる

わけではない。

pathMappingsで対応できるのは

  • ホスト側にも存在するソースコード

だけである。

そのため実務では

  • アプリケーションコード → デバッグ対象
  • ライブラリ内部→ 基本的には対象外

として運用することが多い。

docker-compose.ymlで外部起動する場合

実務ではこちらの方が多い。

例えば以下のようにする。

docker-compose.yml
version: "3"
services:
container_python_remote_debug:
container_name: "container_python_remote_debug"
# Dockerfileをビルド
build:
context: .
dockerfile: Dockerfile
tty: true
# プロジェクトをバインドマウント
volumes:
- .:/app
ports:
- "5678:5678"
command: >
python -m debugpy
--listen 0.0.0.0:5678
--wait-for-client
main.py

この場合は

起動
docker compose up

だけでdebugpy付きのPythonプロセスが起動する。
その後、ホストOS上のVS Codeからattachする。

compose管理のメリット

実務では起動方法を

  • docker-compose.yml

へ集約した方が管理しやすい。

例えば

  • 開発環境
  • CI環境
  • チームメンバー

全員で同じ起動方法を共有できる。
そのため外部起動を利用する場合は、
docker-compose.ymlへ記述する構成が最も実務的である。

同一環境と別環境の本質的な違い

本質的な違いは

  • VS Codeがどこで動いているか

である。

同一環境

同一環境
Dockerコンテナ
├─ VS Code
├─ Python
└─ debugpy

すべてコンテナ上で動く

別環境

別環境
ホストOS
└─ VS Code
Dockerコンテナ
├─ Python
└─ debugpy

ホストとコンテナの別々の環境で動作する

この違いにより、別環境では

  • ports設定
  • 0.0.0.0待受
  • pathMappings

が必要になる。

接続イメージの違い

同一環境では

同一環境
VS Code(コンテナ内)
↓ localhost
debugpy(コンテナ内)

になる。

一方で別環境では

別環境
VS Code(ホスト)
↓ localhost:5678
Docker Port Mapping
debugpy(コンテナ内)

になる。

つまり別環境ではネットワーク越しの接続が発生する。

コンテナ × 別環境の重要ポイント

コンテナ × 別環境では

  • ホスト
    • VS Code
  • コンテナ
    • Python
    • debugpy

が別環境で動作している。

そのため理解すべきポイントは次の4つ。

1. debugpyポートを公開する

docker-compose.yml
ports:
- "5678:5678"

vscodeからアタッチするためのポートを開けておく

2. debugpyは0.0.0.0で待受する

main.py
debugpy.listen(("0.0.0.0", 5678))

または

実行方法
python -m debugpy \
--listen 0.0.0.0:5678

「0.0.0.0」は全NICで待受する

3. pathMappingsを設定する

launch.json
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "/app"
}
]

ホストとコンテナの紐づけ

4. コンテナ内だけに存在するライブラリを理解する

pathMappingsで解決できるのは

  • ホストにも存在するコード

だけである。

site-packages問題は別で考える必要がある。

debugpyの実務的な使い分け

埋め込みが向いているケース

  • 起動方法を変更できない
  • 特定位置で確実に停止したい
  • 一時的な調査

main.py
debugpy.wait_for_client()

を特定位置へ埋め込んで停止したい場合。

外部起動が向いているケース

  • コードを汚したくない
  • Docker Composeで管理したい
  • FastAPIやFlaskを起動する
  • チーム開発を行う

実務ではこちらの方が多い。

実務判断まとめ

実務では

  • FastAPI
  • Flask
  • Django
  • APIサーバ
  • バッチサーバ

などで開発行う場合は

  • コンテナ × 別環境 × attach × 外部起動
  • コンテナ × 同一環境 × attach × 外部起動

のどちらかが最も実用的な構成になる

コンテナ × 別環境 × attach × 外部起動

当記事で紹介した構成

別環境
【コンテナ × 別環境 × 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 × 外部起動

同一環境
【コンテナ × 別環境 × 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 │
└──────────────────────────────┘

詳しくは下記

新着記事

目次
タグ一覧
top