我正在尝试为 VSCode 上的 dockerized Flask 应用程序配置调试器。为了做到这一点,我已经将ptvsd附加到我的应用程序并公开了它的端口。
from flask import Flask, redirect, url_for
app = Flask(__name__)
if app.debug:
print("attaching ptvsd")
import ptvsd
ptvsd.enable_attach(address = ('0.0.0.0', 3000), redirect_output=True)
ptvsd.wait_for_attach()
ptvsd.break_into_debugger()
Dockerfile
FROM python:3
ENV FLASK_APP app/main.py
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD [ "flask", "run", "--host=0.0.0.0" ]
和用于运行容器的命令:
docker run -it --rm -p 5000:5000 -p 3000:3000 -e FLASK_ENV=development webserver
运行容器后,默认情况下不显示任何错误。当我尝试从端口 3000 上的 vscode 附加调试器时,没有任何反应。当我在 Web 浏览器中打开应用程序的任何页面时,将显示以下消息:
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 35, in reraise
raise value
File "/usr/src/app/app/main.py", line 9, in <module>
ptvsd.enable_attach(address = ('0.0.0.0', 3000), redirect_output=True)
File "/usr/local/lib/python3.7/site-packages/ptvsd/attach_server.py", line 101, in enable_attach
ptvsd_enable_attach(address)
File "/usr/local/lib/python3.7/site-packages/ptvsd/_remote.py", line 64, in enable_attach
**kwargs)
File "/usr/local/lib/python3.7/site-packages/ptvsd/pydevd_hooks.py", line 128, in install
daemon = Daemon(**kwargs)
File "/usr/local/lib/python3.7/site-packages/ptvsd/daemon.py", line 503, in __init__
super(Daemon, self).__init__(wait_for_user, **kwargs)
File "/usr/local/lib/python3.7/site-packages/ptvsd/daemon.py", line 100, in __init__
self._install_exit_handlers()
File "/usr/local/lib/python3.7/site-packages/ptvsd/daemon.py", line 425, in _install_exit_handlers
self._exithandlers.install()
File "/usr/local/lib/python3.7/site-packages/ptvsd/exit_handlers.py", line 62, in install
self._install_signal_handler()
File "/usr/local/lib/python3.7/site-packages/ptvsd/exit_handlers.py", line 103, in _install_signal_handler
orig[sig] = signal.signal(sig, self._signal_handler)
File "/usr/local/lib/python3.7/signal.py", line 47, in signal
handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler))
ValueError: signal only works in main thread
有人可以解释我错误消息的含义吗?这个问题的可能解决方案是什么?
多亏了这个回购,我已经想通了。简而言之,PTVSD与Flask的"自动重新加载"功能不兼容。它需要被禁用。
理想情况下,我想保持这两个功能(调试器和自动重新加载(都处于启用状态,但我还没有设法做到这一点。这是我的临时解决方法。
我已经创建了docker-compose.yml
文件。这不是必需的,但简化了启动服务器的过程。
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
- "3000:3000"
environment:
- FLASK_ENV=${FLASK_ENV}
volumes:
- .:/server_apps/webserver
然后我创建了docker-compose.debugger.yml
.
version: '3'
services:
web:
# Replace default run function
# --no-reload is necessary to run PTVSD debugger
command: ["flask", "run", "--no-reload"]
它将默认的运行命令替换为另一个具有--no-reload
参数的命令。
现在,当我开发我的应用程序时,我正在使用
$ docker-compose up
在每次代码更改时部署默认配置(docker-compose.yml
(自动重新加载应用程序。当出现问题并且我想使用调试器时,我键入
$ docker-compose -f docker-compose.yml -f docker-compose.debugger.yml up