调试在 Docker 中运行的 python 应用程序
Posted
技术标签:
【中文标题】调试在 Docker 中运行的 python 应用程序【英文标题】:Debug python application running in Docker 【发布时间】:2017-05-03 06:09:02 【问题描述】:我最近才开始尝试围绕 Docker 进行研究,并设法让开发机器启动并运行。我现在要做的是能够在我的 python 应用程序(特别是 Django)中使用 Visual Studio Code 中的调试器。
我已尝试遵循python extension for VS Code 的有限文档,该文档解释了远程调试的参数。
Dockerfile
FROM python:3.5.2
RUN apt-get update \
--no-install-recommends && rm -rf /var/lib/apt/lists/* \
&& mkdir -p /code \
EXPOSE 8000
WORKDIR /code
COPY requirements.txt /code
RUN /bin/bash --login -c "pip install -r requirements.txt"
ADD . /code
CMD []
docker-compose.yml
version: '2'
services:
db:
image: postgres
web:
build: .
volumes:
- .:/code
ports:
- "8000:8000"
command: bash -c "./wait-for-it.sh db:5432 && python manage.py migrate && python manage.py runserver 0.0.0.0:8000 --noreload"
depends_on:
- db
launch.json
"name": "Attach (Remote Debug)",
"type": "python",
"request": "attach",
"localRoot": "$workspaceRoot",
"remoteRoot": "/code",
"port": 8000,
"secret": "debug_secret",
"host": "localhost"
我还在其中一个项目文件中添加了 ptvsd.enable_attach("debug_secret", address = ('0.0.0.0', 8000))
行
问题
当我启动调试器时,什么都没有发生,看起来 VS Code 正在等待断点命中。但它永远不会。
有什么想法吗?
编辑:小更新
我尝试为调试器使用不同的端口,并在docker-compose.yml
中公开新端口,但没有任何成功。看起来附加是成功的,因为调试器没有崩溃但没有触发断点。我真的被这个卡住了。
解决方案
请参阅 The Barkman 的回答。 我要补充一点,我无法使用秘密来完成这项工作。我做了以下事情:
manage.py
import ptvsd
ptvsd.enable_attach(secret=None, address=('0.0.0.0', '3000'))
launch.json
"name": "Attach Vagrant",
"type": "python",
"request": "attach",
"localRoot": "$workspaceRoot",
"remoteRoot": "/code",
"port": 3000,
"secret": "",
"host":"localhost"
【问题讨论】:
【参考方案1】:通过将 ptvsd 代码放入我的 manage.py 文件并关闭 Django 的实时代码重新加载,我在远程调试 dockerized Django 项目方面取得了最大的成功。
因为当你 runserver
时 Django 基本上启动了 2 个服务器(一个用于实时代码重新加载,另一个用于实际的应用程序服务器`,ptvsd 似乎真的很困惑它应该监视哪个服务器。我可以得到它通过等待附件、尝试/排除 enable_attach 方法或闯入调试器来工作 - 但断点永远不会起作用,而且我似乎一次只能调试一个文件。
如果您在启动服务器时使用 django 标志 --noreload
,则可以将 ptvsd 放入 manage.py 文件中,而无需等待/中断调试器的废话,并享受更强大的调试体验。
manage.py:
import ptvsd
ptvsd.enable_attach(secret='mah_secret', address=('0.0.0.0', 3000))
运行服务器:
python manage.py runserver 0.0.0.0:8000 --noreload
希望这会有所帮助!
【讨论】:
这对我帮助很大!我会将其标记为解决方案,但我应该补充一点,我无法让 ptvsd.enable_attach 使用秘密。我通过在 launch.json 中设置 secret=None 和 secret="" 解决了这个问题。 这很奇怪,我从来没有遇到过附件的机密部分的问题。很高兴你让它工作了!不言而喻,但请确保不会在没有秘密的情况下意外部署;)哈哈【参考方案2】:我试图做一些与你非常相似的事情,并遇到了这个问题/评论:
https://github.com/DonJayamanne/pythonVSCode/issues/252#issuecomment-245566383
其中描述了要使用断点,您需要使用 ptvsd.break_into_debugger()
函数。
举个例子:
import ptvsd
ptvsd.enable_attach(secret='my_secret',address = ('0.0.0.0', 3000))
ptvsd.wait_for_attach()
ptvsd.break_into_debugger()
在我的 python 脚本中添加它后,我的断点就起作用了。希望它有一些用处。
2017 年 1 月 24 日编辑
在我的 DockerFile 中,我安装了 ptvsd:
FROM kaixhin/theano
RUN pip install ptvsd
WORKDIR /src
EXPOSE 3000
ENTRYPOINT ["python","src/app.py"]
COPY . /src
看起来您通过 requirements.txt 文件安装的依赖项是 ptvsd 在您的 requirements.txt 中吗?
【讨论】:
谢谢!我回家后试试这个 无法让它工作......也许我做错了什么。您将 ptvsd 函数调用放在哪里(哪个文件)? @Mattias 我刚刚添加了我的 DockerFile 的引用,您是在 docker 容器中安装 ptvsd 吗? 我的意思是,我应该把 ptvsd 函数调用放在哪里?我需要将它放在每个文件中还是只在一个文件中?您能否显示使用 ptvsd 的整个代码?谢谢 我想我现在已经完成了一半......现在的问题似乎是调试器在几秒钟后停止。所以我无法验证调试器是否真的在工作。【参考方案3】:一些故障排除技巧:
1) 确保您的调试端口已打开。从您的主机运行它。
nc -zv test.example.com 30302
2) 确保您的 webserve 不会自动重新加载您的应用。这将中断调试器连接。在启动时运行的代码中添加打印或日志语句,以确保您的应用程序不会被加载两次。这适用于在烧瓶上运行的 socketio。但 django 和其他网络服务器也有类似的东西。
socketio.run(app, host="0.0.0.0", port=5000, debug=True, use_reloader=False)
【讨论】:
以上是关于调试在 Docker 中运行的 python 应用程序的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 IntelliJ 调试在 Docker 中运行的应用程序?
在 JetBrains Rider 中调试从 docker compose 运行的 .Net Core 3 应用程序
如何通过 Google Cloud 调试在 Docker 容器中运行的 Nodejs 应用程序
IntelliJ 在 Docker 中调试 Java 应用程序
如何在 Mac 上使用 JetBrains Rider 开发和调试在 Docker 中运行的 .NET Core 应用程序