在 PyCharm 中逐行调试 Docker 部署的 Python 微服务 RESTful API,核心是让 PyCharm 与容器内的 Python 进程建立调试连接,实现本地 IDE 控制容器内代码的断点、步进等调试操作。下面分两种最实用的方案(远程调试 + 容器化调试配置),从环境准备到实操步骤全覆盖,新手也能快速上手。
前置条件
- 你的 Python 微服务代码已在 PyCharm 中打开(本地代码需与容器内代码完全一致,包括版本、路径);
- 容器内已安装调试依赖:
pip install pydevd-pycharm~=202X.X(版本需匹配你的 PyCharm 版本,比如 PyCharm 2024.1 对应pydevd-pycharm~=241.xxx); - Docker 容器启动时,需映射调试端口(默认 5678),并保证宿主机能访问该端口。
方案一:远程调试(最通用,适合已部署的容器)
这是针对已运行的 Docker 容器的调试方案,无需修改容器启动方式,只需在代码中加入调试入口,再通过 PyCharm 连接容器。
步骤 1:修改 Python 微服务代码,加入调试入口
在微服务的启动文件 (如 app.py,Flask/FastAPI 均适用)开头加入调试代码,确保容器启动时能监听调试端口:
:
python
运行
# app.py(Flask 示例,FastAPI 同理)
from flask import Flask, jsonify
import sys
# ===== 调试核心代码(仅调试环境开启)=====
try:
import pydevd_pycharm
# 配置:宿主机IP(容器能访问到的IP) + 调试端口(默认5678)
pydevd_pycharm.settrace(
'192.168.1.100', # 替换为你的宿主机内网IP(容器要能ping通)
port=5678,
stdoutToServer=True,
stderrToServer=True,
suspend=False # 设为False:启动时不阻塞;设为True:启动后等待调试连接
)
except ImportError:
print("pydevd-pycharm 未安装,跳过调试配置")
# ======================================
app = Flask(__name__)
# 示例API:加断点调试
@app.route('/api/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
# 在这里打个断点 ↓
user = {"id": user_id, "name": "test", "age": 20}
return jsonify(user)
if __name__ == '__main__':
# 容器内启动服务,监听0.0.0.0(允许外部访问)
app.run(host='0.0.0.0', port=8080)
步骤 2:启动 Docker 容器(映射调试端口 + API 端口)
启动容器时,需同时映射调试端口(5678) 和 API 端口(8080),并保证容器能访问宿主机的 5678 端口:
bash
运行
# 关键参数:-p 5678:5678(调试端口) -p 8888:8080(API端口)
docker run -d \
-p 5678:5678 \
-p 8888:8080 \
--name python-api \
# 可选:如果宿主机是Windows/Mac,加--add-host映射宿主机IP(避免容器解析不到)
--add-host=host.docker.internal:host-gateway \
python-api-image:latest
方案二:PyCharm 直接运行 / 调试 Docker 容器(更便捷,适合开发阶段)
如果是开发阶段,可以让 PyCharm 直接管理 Docker 容器的启动和调试,无需手动改代码加调试入口,步骤更简化。
步骤 1:PyCharm 配置 Docker 连接
步骤 2:创建 Docker Compose / 容器运行配置
以 Docker Compose 为例(单容器同理):
步骤 3:直接在 PyCharm 中调试
常见问题排查
总结
--add-host=host.docker.internal:host-gateway:Docker 20.10+ 版本可用,容器内可通过host.docker.internal访问宿主机(替代手动写宿主机 IP),代码中settrace的 IP 可改为host.docker.internal。
步骤 3:PyCharm 配置远程调试连接
- 打开 PyCharm → 点击右上角「Add Configuration...」;
- 点击「+」→ 选择「Python Debug Server」;
- 配置调试服务器:
- Name:自定义(如
Docker Python API Debug); - Host:填
0.0.0.0(监听所有网卡); - Port:填
5678(和代码中一致);
- Name:自定义(如
步骤 4:开始逐行调试
-
在 PyCharm 中找到需要调试的 API 代码行(如
get_user函数内),点击行号左侧打断点(红色圆点); -
点击 PyCharm 右上角的「调试按钮」(绿色小虫子),启动调试服务器;
-
访问 API 触发断点: bash
运行
# 宿主机访问API,触发断点 curl http://localhost:8888/api/users/1 -
此时 PyCharm 会自动暂停在断点处,你可以:
- 逐行执行(F8)、进入函数(F7)、跳出函数(Shift+F8);
- 查看变量值(Debug 面板 → Variables);
- 修改变量值(右键变量 → Set Value);
- 查看调用栈(Debug 面板 → Frames)。
-
打开 PyCharm → 「File」→「Settings」→「Build, Execution, Deployment」→「Docker」;
-
点击「+」,选择 Docker 连接方式(本地 Docker 选「Docker for Windows/Mac/Linux」);
-
点击「Apply」→「OK」,PyCharm 会自动识别本地 Docker 环境。
-
点击右上角「Add Configuration...」→「+」→「Docker Compose」;
-
配置:
- Name:自定义(如
Docker Compose API); - Compose file (s):选择你的
docker-compose.yml文件; - Service:选择要调试的微服务(如
python-api); - 切换到「Debug」标签:
- 勾选「Debug container」;
- Python interpreter path:填容器内的 Python 路径(如
/usr/local/bin/python); - Path mappings:映射本地代码路径 → 容器内代码路径(关键!必须一致),比如:
- Local path:
/Users/xxx/project/python-api(本地代码根目录); - Remote path:
/app(容器内代码目录);
- Local path:
- Name:自定义(如
-
点击「OK」保存。
-
在代码中打断点(如
get_user函数); -
点击右上角「调试按钮」(绿色小虫子),PyCharm 会自动:
- 构建 / 启动 Docker 容器;
- 注入调试器;
- 监听调试端口;
-
访问 API(
curl http://localhost:8888/api/users/1),PyCharm 会自动暂停在断点处,实现逐行调试。 -
调试连接失败:
- 检查容器内是否安装了对应版本的
pydevd-pycharm(PyCharm →「Help」→「About」查看版本,如 2024.1,安装pip install pydevd-pycharm~=241.15989); - 检查宿主机 IP 是否正确,容器能否 ping 通宿主机(
docker exec -it python-api ping 192.168.1.100); - 检查防火墙 / 安全组是否开放 5678 端口。
- 检查容器内是否安装了对应版本的
-
断点不命中:
- 确保本地代码路径和容器内代码路径完全一致(Path mappings 配置正确);
- 确保代码版本一致(本地修改后需重新构建容器镜像);
- 断点打在「实际执行的代码行」(如不要打在空行、注释行)。
-
容器启动阻塞:
- 代码中
suspend=True会导致容器启动后等待调试连接,改为suspend=False即可。
- 代码中
-
核心原理 :通过
pydevd-pycharm建立 PyCharm 与容器内 Python 进程的调试通道,映射调试端口实现断点控制; -
方案选择:已部署的容器用「远程调试」(改代码 + 映射端口),开发阶段用「PyCharm 直接管理 Docker」(更便捷);
-
关键配置:保证宿主机与容器的网络互通、代码路径映射一致、调试端口开放。