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

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

作成日:2026月05月16日
更新日:2026年05月23日

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

  • debugpy

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

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

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

がある。

詳しくは下記記事参照

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

  • Pythonをコンテナでデバッグするパターン
  • コンテナ × 同一環境
  • launch / attach

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

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

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

  • VS CodeとPythonが同じDockerコンテナ内で動作するデバッグ

のこと。

ここでいう同一環境とは

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

が同じコンテナ内にあるという意味。

つまり

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

のような構成になる。

逆に、ホストOS上のVS Codeからコンテナ内Pythonへ接続する構成は

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

になる。

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

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

  • VS CodeとPythonが同じコンテナ内
  • コンテナ内のPython環境をそのまま使える
  • 本番に近い依存関係で動作確認できる
  • ホストOSにPythonをインストールしなくてよい
  • pathMappingsを意識しなくてよい
  • 同一コンテナ内なのでデバッグ用ポート公開が不要

といった特徴がある。

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

実際の開発では、Pythonをローカルではなく

  • Dockerコンテナ上で実行する

ことが多い。

その理由は

  • 開発者ごとの差分をなくす
  • OSやライブラリの差分をなくす
  • 本番に近い環境で動作確認する
  • Pythonや依存ライブラリをホストOSに入れない

ため。

そのため、コンテナ内でVS Codeを操作し、同じコンテナ内のPythonをデバッグできるようにしておくと便利。

デバッグ構成の全体像

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

  • コンテナ × launch
  • コンテナ × attach × 埋め込み
  • コンテナ × attach × 外部起動

それぞれのパターン別に実装して動作を確認する。

前提構成

今回の構成は以下。

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

requirements.txt

requirements.txt
debugpy
  • launch実行の場合は、実はVScode側でdebugpyを自動インジェクションしてくれるので不要(拡張機能ms-python.pythonのインストールは必要)
  • attach実行の場合は、スクリプトを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 /workspace
# 依存関係を先にコピー(レイヤーキャッシュ最適化)
COPY requirements.txt .
# パッケージインストール(キャッシュ無効)
RUN pip install --no-cache-dir -r requirements.txt

docker-compose.yml

docker-compose.yml
version: "3"
services:
python3:
container_name: "container_python3"
# Dockerfileをビルド
build:
context: .
dockerfile: Dockerfile
tty: true
# プロジェクトをバインドマウント
volumes:
- .:/workspace
ports:
- "1000:8888"
  • ソースコードをコンテナへマウントする
  • /workspace を作業ディレクトリにする
  • tty: true でコンテナを起動状態にしておく

VScodeからコンテナへアタッチする

VScodeで上記のプロジェクトを開く
VScodeでコンテナにアタッチするための拡張機能として
2026-05-23-17-21-50

  • ms-vscode-remote.remote-containers
    をインストールしておく。

コンテナ起動

上記プロジェクト直下で

コンテナ起動
docker compose up -d

を実行してコンテナを起動させる

コンテナにアタッチする

2026-05-23-17-26-30
新しいウィンドウでアタッチする

2026-05-23-17-27-43 VScodeでコンテナを開くことができる

これで

  • VS Code
  • Python
  • debugpy

が同じコンテナ内で動作する構成になる。

launchデバッグ

launchはVS CodeがPythonプロセスを起動してデバッグする方式。

コンテナ × 同一環境では

  • VS Codeがコンテナ内で動いている
  • Pythonも同じコンテナ内にある

ため、VS Codeからコンテナ内Pythonを直接起動できる。

仕組み

仕組みは

launchの仕組み
VS Code(コンテナ内)
↓(起動)
Python(コンテナ内 / debugpy付き)
デバッグ開始

のようになるイメージ。

VS CodeがPythonをdebugpy付きで実行させることでデバッグを開始する。

launchデバッグ実装例

実際にコンテナ内Pythonをlaunchデバッグしてみる。

作成するファイルは

  • launch.json
  • main.py

で構成は

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

になる。

.vscode/launch.json

VS Codeの実行とデバッグから作成できる。

launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Python デバッガー: コンテナ launch",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/main.py",
"console": "integratedTerminal"
}
]
}
  • ${workspaceFolder} はコンテナ内の /workspace を指す
  • 同一コンテナ内なので pathMappings は不要

main.py

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

実行方法

  • コンテナをVS Codeを開く
  • F5キーで実行
  • ブレークポイントが有効

launchではVS CodeがPythonプロセスを起動するため、最もシンプルにコンテナ内デバッグできる。
2026-05-16-17-07-21

attachデバッグ

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

コンテナ × 同一環境でもattachではdebugpyの起動形態が

  • 埋め込み
  • 外部起動

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

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

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

仕組み

埋め込みの仕組み
debugpyを埋め込んだPython(コンテナ内で実行中)
VS Code(同じコンテナ内)が接続

のようになるイメージ。 launchデバッグとは異なり, VS CodeがPythonをdebugpy付きで実行はしてくれないので
debugpy埋め込み済みのPythonをコンテナ内で実行し、
同じコンテナ内のVS Codeからアタッチしてデバッグを開始する。

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

実際にdebugpy埋め込み済みPythonスクリプトをattachデバッグしてみる。

作成するファイルは

  • launch.json
  • main.py

で構成は

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

になる。

main.py

main.py
import debugpy
# デバッグクライアント(VS Codeなど)からの接続を受け付けるためのサーバを起動する
debugpy.listen(5678)
# デバッグクライアントが接続されるまで、ここでプログラムの実行を完全に停止する
debugpy.wait_for_client()
def main():
print("hello1")
print("hello2")
print("hello3")
print("hello4")
print("hello5")
if __name__ == "__main__":
main()
  • debugpyのコードを埋め込む
  • 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": "/",
"remoteRoot": "/"
}
]
}
]
}
  • connectでdebugpyサーバが待ち受けているアドレスを指定する
  • VS Codeも同じコンテナ内なので localhost:5678 で接続できる
  • justMyCodeをfalseにすることサードパーティーライブラリの中もデバッグできる

pathMappingsについて

pathMappingsは本来は

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

のようにローカルからコンテナをリモートデバッグする際にVSCodeのdebugpyが

  • ローカル側のファイルパス
  • Python実行側(コンテナ・リモート)のファイルパス

を相互変換するための設定である。

ただ今回のようにDev Containerを使ってVSCodeでコンテナにアタッチしてる場合、
VS Code側とPython側はどちらもコンテナ内のLinuxパスを参照するので ホストOSのパスとコンテナ内パスを変換する必要はない。

ただし、Pythonが実行するコードが必ず /workspace 配下にあるとは限らない。
コンテナビルド時にインストールされたパッケージやライブラリは、site-packages など /workspace 外に配置される場合がある。

そのため「パスを書き換えるため」の設定ではなく
同一コンテナ内のパスをそのまま対応付ける目的で次のように設定する。

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

としておくと実務上扱いやすい。 これにより /workspace 外に配置された site-packages なども含めて、同一コンテナ内のパスをそのまま解決できるようになる。

なお、pathMappingsを書かない場合でも、VS Code側とPython実行側のパスが完全一致していれば動作することは多い。
ただし、実行されるコードが site-packages 側になる場合など、VS Codeが認識しているパスとPython実行時の実体パスがズレると

  • ブレークポイントが効かない
  • 別ファイルとして開かれる
  • ソースが見つからない

といった問題が発生する場合がある。
※launch起動の場合はVS Code自身がPythonプロセスを起動するので不要

実行方法

まずはコンテナ内でPythonスクリプトを実行する。

実行
python main.py

2026-05-16-17-13-46
実行後はVS Codeからの接続があるまで、プログラムが待っているので動かない。
その後にVS Codeのattachデバッガを実行すると、デバッグが開始される。

debugpy起動形態:外部起動(python -m debugpy)

「debugpy起動形態:外部起動」はdebugpyを実行時に指定して起動する方式。

具体的には起動するコマンドで指定する。

仕組み

外部起動仕組み
python -m debugpy
対象スクリプト実行
VS Code(同じコンテナ内)が接続

のようになるイメージ。
こちらもlaunchデバッグとは異なり, VS CodeがPythonをdebugpy付きで実行はしてくれないので
Pythonを実行するコマンドでdebugpyを指定する。
その後、VS Codeからアタッチしてデバッグを開始する。

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

実際にPythonスクリプトをdebugpy付きで外部起動してattachデバッグしてみる。

作成するファイルは

  • 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

debugpy起動形態:埋め込み実装例と同じ

launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Python デバッガー: attach",
"type": "debugpy",
"request": "attach",
"justMyCode": false,
"connect": {
"host": "localhost",
"port": 5678
},
"pathMappings": [
{
"localRoot": "/",
"remoteRoot": "/"
}
]
}
]
}

実行方法

まずはコンテナ内でPythonスクリプトをdebugpy付きで実行する。

実行
python -m debugpy --listen 5678 --wait-for-client main.py
  • スクリプトの場合は --wait-for-client を指定しないと終了してしまうので指定する
  • FastAPIなどのREST APIの場合は --wait-for-client を指定しなくても問題ない

その後にVS Codeのattachデバッガを実行すると、デバッグが開始される。

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

外部起動はdocker-compose.ymlのcommandに書くこともできる。

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

docker-compose.yml
services:
app:
build: .
tty: true
working_dir: /workspace
volumes:
- .:/workspace
command: python -m debugpy --listen 5678 --wait-for-client main.py

この場合は

起動
docker compose up

でdebugpy付きのPythonプロセスが起動する。
その後、同じコンテナ内で開いたVS Codeからattachする。

ただし、スクリプトでは実行後に終了してしまうため、
--wait-for-client を指定しておくと動作確認しやすい。

launchとattachの本質的な違い

launchとattachの違いは「誰がPythonプロセスを起動するか」にある。

  • launch
    • VS Codeがdebugpy付きでPythonプロセスを起動する
  • attach
    • 既に動いているPython(debugpy付きで起動された)に後から接続する

コンテナ × 同一環境の場合でも、この違いは同じ。

  • launch
    • VS Codeがコンテナ内でdebugpy付きでPythonを起動する
  • attach
    • コンテナ内で起動済みのPython(debugpy付きで起動された)へVS Codeが接続する

という違いになる。

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

コンテナ × 同一環境では

  • VS Code
  • Python
  • debugpy

が同じコンテナ内で動作している。

そのため

  • localhost で接続できる
  • pathMappings が不要
  • ホストへデバッグポートを公開しなくてよい

という特徴がある。

これは

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

という接続になるため。

一方で、ホストOS上のVS Codeからコンテナ内Pythonへ接続する場合は

別環境
VS Code(ホスト)
↓ ポート公開
debugpy(コンテナ内)

になる。

この場合は

  • ports設定
  • 0.0.0.0待受
  • pathMappings

が必要になる。

今回の記事はあくまで

  • コンテナ × 同一環境

のため、そこまでは扱わない。

実務的な使い分け

実際に実務ではどう使い分けるべきかをまとめておく。

launchを使うべきケース

  • コンテナ内での単体スクリプト開発
  • 起動コマンドを自由に変更できる
  • とにかく簡単にデバッグしたい
  • VS Codeから直接Pythonを起動したい

のように、コンテナ内で簡単なPythonツールの動作確認や開発をする場合に使うことが多い。

attachを使うべきケース

  • 既に動いているプロセスをデバッグしたい
  • docker composeで起動したプロセスをデバッグしたい
  • 起動フローを変更できない
  • 長時間動くプロセスをデバッグしたい
  • APIサーバなどをデバッグしたい

のように、実際のシステム開発ではAPIサーバーを起動して、
VS Codeでアタッチしてデバッグする場合に使うことが多い。

attachの中での使い分け

attachはさらに2パターンに分かれる。

  • debugpy埋め込み
  • debugpy外部起動

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

  • 起動方法を変更できない
  • 特定の位置で確実に止めたい

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

  • コードを汚したくない
  • 起動コマンドを制御できる
  • docker-compose.ymlでcommandを管理したい

実務判断まとめ

  • コンテナ内で単体開発

    • launch
  • docker composeで起動するアプリ

    • attach
  • attach内の選択

    • 起動制御できる → 外部起動
    • できない → 埋め込み

まとめると

  • launchは「IDE主導でプロセスを起動するデバッグ」
  • attachは「外部で起動されたプロセスに接続するデバッグ」

という違いになる。

実務では

  • コンテナ内単体開発 → launch
  • docker composeで動くAPIサーバ・バッチ → attach

となることが多い。

特にコンテナ環境では

  • アプリ起動
  • デバッグ接続

を分離できるattachが重要になる。

関連記事

新着記事

目次
タグ一覧
top