调试在Docker中运行的python应用程序

时间:2016-12-17 17:55:47

标签: python django docker visual-studio-code docker-compose

我刚刚开始尝试绕过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 []

搬运工-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中公开新端口但没有成功。看起来attach是成功的,因为调试器没有崩溃,但没有触发断点。我真的坚持这个。

解决方案

见巴克曼的回答。 我要补充一点,我无法使用秘密来实现这一目标。我做了以下事情:

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"
    }

3 个答案:

答案 0 :(得分:4)

通过将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

希望这有帮助!

答案 1 :(得分:3)

我试图做一些与你非常相似的事情并遇到了这个问题/评论:

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 文件安装依赖项吗?

答案 2 :(得分:0)

几个麻烦的拍摄提示:

1)确保您的调试端口已打开。从您的主机运行。

  

nc -zv test.example.com 30302

2)确保您的网站不会自动重新加载您的应用。这将打破调试器连接。在您的代码中放置一个打印或日志语句,该代码在启动时运行,以确保您的应用程序未加载两次。这是用于在烧瓶上运行的socketio。但是django和其他网络服务器有类似的东西。

  

socketio.run(app,host =" 0.0.0.0",port = 5000,debug = True,use_reloader = False)