在 VS Code 里对 Docker 容器中的 Python 做单步调试,最常用两种方式:直接附加到运行容器 (简单快速)、远程 attach 调试(灵活可控)
一、准备工作(必做)
-
安装 VS Code 扩展
- Python(微软官方)
- Docker(微软官方)
- Dev Containers(可选,用于直接进入容器开发)
-
项目结构示例
plaintext
your-project/ ├── app.py # 你的 Python 代码 ├── Dockerfile ├── requirements.txt └── .vscode/ ├── launch.json # 调试配置 └── tasks.json # 构建/运行任务(可选)
二、方式一:直接附加到运行容器(推荐新手)
1. 编写 Dockerfile
dockerfile
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 安装 debugpy(调试必备)
RUN pip install debugpy
COPY . .
# 启动命令:用 debugpy 监听 0.0.0.0:5678,等待客户端连接
CMD ["python", "-m", "debugpy", "--listen", "0.0.0.0:5678", "--wait-for-client", "app.py"]
2. 构建并运行容器(暴露调试端口)
bash
运行
# 构建镜像
docker build -t my-python-app .
# 运行容器,映射调试端口 5678
docker run -d -p 5678:5678 --name my-python-container my-python-app
3. VS Code 附加调试
-
打开你的项目
-
左侧「运行和调试」(Ctrl+Shift+D)→ 「创建 launch.json 文件」
-
选择 Python → Remote Attach
-
修改
.vscode/launch.json:json
{ "version": "0.2.0", "configurations": [ { "name": "Python: Attach to Docker", "type": "debugpy", "request": "attach", "connect": { "host": "localhost", "port": 5678 }, "pathMappings": [ { "localRoot": "${workspaceFolder}", "remoteRoot": "/app" } ], "justMyCode": false } ] } -
在
app.py打断点 -
选择配置「Python: Attach to Docker」→ 按 F5 启动调试
-
即可单步调试(F10 单步跳过、F11 单步进入、F5 继续)
三、方式二:用 Dev Containers 直接在容器内开发(最顺滑)
1. 一键生成 Docker 配置
- Ctrl+Shift+P → 输入 Dev Containers: Add Development Container Configuration Files...
- 选择 Python 3 → 选择版本 → 生成
.devcontainer/配置
2. 重新在容器中打开项目
- Ctrl+Shift+P → Dev Containers: Reopen in Container
- VS Code 会自动构建镜像、启动容器,并在容器内打开项目
3. 直接调试(和本地一样)
- 在容器内的 VS Code 窗口中,直接打断点
- 按 F5 → 选择 Python File
- 即可单步调试,无需额外端口映射
四、方式三:docker-compose + 调试(适合多服务)
1. docker-compose.yml
yaml
version: '3'
services:
app:
build: .
ports:
- "5678:5678" # 调试端口
volumes:
- .:/app # 本地代码映射到容器,热更新
command: python -m debugpy --listen 0.0.0.0:5678 --wait-for-client app.py
2. 启动
bash
运行
docker-compose up -d
3. 调试
- 同方式一,用
launch.json附加到localhost:5678
五、关键配置说明
- debugpy:VS Code Python 调试的官方后端,必须安装
- --listen 0.0.0.0:5678:容器内监听所有网卡,允许外部连接
- --wait-for-client:程序启动后暂停,直到 VS Code 附加成功
- pathMappings :必须正确 ,否则断点不生效
localRoot:本地项目路径(${workspaceFolder})remoteRoot:容器内代码路径(如/app)
六、常见问题
-
断点不命中
- 检查
pathMappings是否匹配 - 确保容器内安装了
debugpy - 重启容器与 VS Code
- 检查
-
连接超时
- 检查端口映射
5678:5678是否正确 - 防火墙是否放行 5678 端口
- 容器是否正常运行(
docker ps)
- 检查端口映射
-
代码修改不生效
- 用
volumes映射本地代码到容器 - 或在容器内重新安装依赖
- 用
七、单步调试快捷键
- F5:继续运行
- F10:单步跳过(不进入函数)
- F11:单步进入(进入函数)
- Shift+F11:单步跳出
- Ctrl+Shift+F5:重启调试
- Shift+F5:停止调试
参考一:
这个命令的执行位置分两种核心场景,我会用新手能直接看懂的方式讲清楚,还会补充关键注意事项:
一、核心执行位置(两种方式)
方式 1:作为容器启动命令(推荐,无需手动进容器)
这是最常用的方式,你不需要手动登录容器执行,而是把这个命令写在 Dockerfile/docker-compose.yml 里,容器启动时会自动执行。
-
✅ 写在 Dockerfile 的
CMD/ENTRYPOINT中(对应之前示例):dockerfile
# Dockerfile 末尾 CMD ["python", "-m", "debugpy", "--listen", "0.0.0.0:5678", "--wait-for-client", "app.py"] -
✅ 写在 docker-compose.yml 的
command中:yaml
services: app: build: . ports: ["5678:5678"] # 容器启动时自动执行该命令 command: python -m debugpy --listen 0.0.0.0:5678 --wait-for-client app.py
方式 2:手动进入容器内部执行(调试 / 排查用)
如果想临时调试,或容器已启动,可手动登录容器执行:
-
先启动一个基础容器(暴露端口,映射代码): bash
运行
# 启动容器(后台运行,映射端口和代码) docker run -it -d -p 5678:5678 -v $(pwd):/app --name debug-container python:3.10-slim -
进入容器的交互式终端: bash
运行
# 登录容器(进入容器内部的命令行) docker exec -it debug-container /bin/bash -
在容器内切换到代码目录,执行命令: bash
运行
# 容器内执行(先安装 debugpy,再启动调试) cd /app # 切换到代码所在目录(必须和你的代码路径一致) pip install debugpy python -m debugpy --listen 0.0.0.0:5678 --wait-for-client app.py
二、关键注意事项(新手必看)
- 执行目录必须正确 :命令中的
your_application.py是容器内的路径 ,必须确保执行命令时的工作目录能找到这个文件(比如用cd /app切换到代码目录)。 - 必须安装 debugpy :执行命令前,容器内必须先装
debugpy(可写在 Dockerfile 里,或手动pip install debugpy)。 - 端口必须暴露 :启动容器时要加
-p 5678:5678(映射端口),否则 VS Code 连不上容器内的 5678 端口。
总结
- 日常开发优先把命令写在 Dockerfile/docker-compose.yml 中,容器启动时自动执行,无需手动操作;
- 临时调试可通过
docker exec -it进入容器,在容器内的代码目录执行该命令; - 核心前提:容器内安装 debugpy + 端口映射 5678 + 执行目录能找到目标 Python 文件。
参考二:
第一步:先确认容器内的 debugpy 服务是否正常运行
这是最核心的前提,先通过命令行验证容器侧状态:
1. 检查容器是否在运行
bash
运行
# 查看所有运行中的容器
docker ps
# 如果容器没运行,先启动:docker start 容器名/容器ID
- 如果容器未运行 → 先启动容器,再继续排查。
2. 进入容器,检查 debugpy 是否在监听 5678 端口
bash
运行
# 进入容器终端
docker exec -it 你的容器名/容器ID /bin/bash
# 在容器内执行,检查 5678 端口是否被占用
netstat -tulpn | grep 5678
# 或用 python 检查(如果没有 netstat)
python -c "import socket; s = socket.socket(socket.AF_INET, socket.SOCK_STREAM); print(s.connect_ex(('0.0.0.0', 5678)))"
-
✅ 正常结果:
netstat能看到python进程监听0.0.0.0:5678;python命令返回0(端口可连接)。 -
❌ 异常结果:无输出 / 返回
111→ 说明 debugpy 没启动,重新执行:bash
运行
# 容器内重新启动 debugpy(替换为你的脚本路径) pip install debugpy # 确保安装 python -m debugpy --listen 0.0.0.0:5678 --wait-for-client /app/你的脚本.py
3. 本地测试能否连接容器的 5678 端口
bash
运行
# 本地执行(Windows 用 telnet 或 PowerShell)
telnet localhost 5678
# 或 PowerShell:Test-NetConnection localhost -Port 5678
-
✅ 正常:连接成功 /
TcpTestSucceeded: True。 -
❌ 异常:连接拒绝 → 检查容器启动命令是否加了
-p 5678:5678(端口映射),重新启动容器:bash
运行
docker run -d -p 5678:5678 --name 容器名 镜像名
第二步:检查 VS Code 调试配置(launch.json)
配置错误是断点 / 调试无反应的高频原因,重点核对以下项:
1. 完整的正确配置模板(直接替换你的 launch.json)
json
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Attach to Docker",
"type": "debugpy",
"request": "attach",
"connect": {
"host": "localhost",
"port": 5678,
"timeout": 10000 // 增加超时时间,避免连接慢导致无响应
},
"pathMappings": [
{
"localRoot": "${workspaceFolder}", // 本地项目根目录(必须正确)
"remoteRoot": "/app" // 容器内代码路径(必须和容器内实际路径一致)
}
],
"justMyCode": false,
"logToFile": true // 开启日志,方便排查
}
]
}
2. 重点核对 3 个关键项
- port:必须和容器内 debugpy 监听的端口一致(默认 5678)。
- pathMappings :
localRoot:本地项目路径,比如你的项目在D:\code\python-docker,就写这个路径(或用${workspaceFolder},但要确保 VS Code 打开的是项目根目录)。remoteRoot:容器内代码的实际路径(比如你在 Dockerfile 中WORKDIR /app,或挂载本地代码到/app,就写/app)。❗ 路径不匹配 → 调试无反应 / 断点不命中。
- host :本地调试填
localhost即可,不要填容器 IP。
第三步:VS Code 侧的额外排查
1. 检查扩展是否正常
- 确保安装了 Python(微软官方) 和 Docker 扩展,且版本最新。
- 重启 VS Code(有时扩展加载异常会导致调试无响应)。
2. 查看调试日志(定位具体错误)
- 按
F1→ 输入Python: Show Debug Log→ 打开日志面板。 - 再次按 F5 启动调试,查看日志中的错误信息:
Connection refused→ 端口映射 / 容器服务问题。Path mapping not found→ 路径映射错误。Timeout→ 网络 / 容器启动慢,增加timeout配置。
3. 确认断点是否有效
- 断点需打在可执行代码行(比如函数内、循环内),不要打在注释、空行、import 行。
- 断点图标是 红色实心点 → 有效;灰色空心点 → 无效(路径映射错误 / 代码未加载)。
第四步:最简验证方案(快速定位问题)
如果以上排查仍无反应,用以下极简步骤重新验证:
-
新建一个空项目,创建
app.py:python
运行
print("开始调试") a = 1 b = 2 c = a + b # 在这里打断点 print(f"结果:{c}") -
创建
Dockerfile:dockerfile
FROM python:3.10-slim WORKDIR /app COPY app.py . RUN pip install debugpy CMD ["python", "-m", "debugpy", "--listen", "0.0.0.0:5678", "--wait-for-client", "app.py"] -
构建并启动容器:
bash
运行
docker build -t test-debug . docker run -p 5678:5678 --name test-debug-container test-debug -
按之前的步骤配置
launch.json,然后按 F5 调试。- 如果这个极简示例能正常调试 → 说明你的原项目配置 / 代码有问题。
- 如果仍无反应 → 检查 VS Code / 系统环境(比如防火墙拦截 5678 端口)。
总结
- 核心前提 :容器内 debugpy 必须监听 5678 端口,且本地能连接该端口(
telnet localhost 5678验证)。 - 关键配置 :
launch.json中的pathMappings必须精准匹配本地 / 容器代码路径。 - 快速验证:用极简项目排除代码 / 配置复杂度,定位问题根源。