在VS Code中调试Docker内Python应用为何执行两次?
为何在Docker容器中调试Python应用会执行两次?
这是VS Code Docker扩展调试Python应用的正常流程设计,原因可以从你看到的两条命令拆解来看:
两条命令的实际作用
主机端调试代理命令:
(venv) user@/: /usr/bin/env /Users/user/DEV/app/venv/bin/python /Users/user/.vscode/extensions/ms-azuretools.vscode-docker-1.23.3/resources/python/launcher.py 65378 -- -m gunicorn --reload --bind 0.0.0.0:8082 app:server docker app-dev这条是VS Code Docker扩展在本地主机上启动的调试代理程序,作用是建立主机与容器之间的调试通信桥接,监听指定端口(65378),负责把VS Code的调试请求转发到容器内的debugpy调试器。
容器内实际应用启动命令:
docker exec -d app-dev python3 /debugpy/launcher host.docker.internal:65378 -- -m gunicorn --reload --bind 0.0.0.0:8082 app:server这条才是真正在Docker容器内启动带调试能力的Python应用的命令,通过
docker exec进入运行中的容器,启动debugpy并让它连接到主机上的代理端口,这样VS Code就能远程控制容器内的应用调试。
重复输出的原因
你看到的两行重复的端口监听日志:
The application is listening on the following port(s) (Host => Container): localhost:8082 => 8082
分别来自两个环节:
- 主机端的调试代理程序会模拟输出应用启动状态日志,用来反馈调试通道已建立;
- 容器内实际启动的gunicorn应用本身也会输出端口监听日志。
看起来像是执行了两次,但实际上真正运行的应用进程只有容器内的那一个,主机端的代理只是负责调试通信的中间件,不会运行你的业务代码。
关于热重载的子进程问题
你理解的完全正确:gunicorn的--reload模式下,当检测到代码文件变更时,会自动退出旧的应用进程并启动新的子进程,VS Code调试控制台会记录所有与调试会话关联的进程日志,所以会看到新增的子进程条目,这是正常的调试跟踪行为。
内容的提问来源于stack exchange,提问作者michuhu
相关产品推荐
相关产品推荐

