如何在Docker容器内运行pdb调试工具

15

我在这里显然有些不理解。我正在尝试在Docker容器内交互式运行pdb调试器。

以下是一些代码:

Dockerfile:

FROM python:3.6
ENV PROJECT_DIR=/opt/foo
WORKDIR $PROJECT_DIR
COPY . .
RUN pip install -r requirements.txt
CMD ["python", "foo.py"]

foo.py:

def hello_world():
    print("hello world")
if __name__ == '__main__':
    #import pdb; pdb.set_trace()
    hello_world()

如果我运行docker build -t foo .,然后运行docker run foo,它会按预期输出“hello world”。
但是,如果我取消注释上面的pdb.set_trace()调用,然后再试一次,我会收到以下错误:
/opt/foo/foo.py(8)<module>()
-> hello_world()
(Pdb) 
Traceback (most recent call last):
  File "foo.py", line 8, in <module>
    hello_world()
  File "foo.py", line 8, in <module>
    hello_world()
  File "/usr/local/lib/python3.6/bdb.py", line 51, in trace_dispatch
    return self.dispatch_line(frame)
  File "/usr/local/lib/python3.6/bdb.py", line 70, in dispatch_line
    if self.quitting: raise BdbQuit
bdb.BdbQuit

我哪里没有理解?


编辑: 在调试Python时出现BbdQuit错误不是重复问题。

正如@soundstripe所正确指出的那样,我的问题是在Docker中未提供pdb的交互式访问。


可能是 Bdbquit raised when debugging python 的重复问题。 - C.Nivs
2个回答

23

Soundstripe提供的技巧对我无效。不过你可以打开一个新终端并输入

docker attach [container_name]

现在你应该可以使用pdb了。

为了使其工作,您可能需要将这些内容添加到docker-compose yml文件中的服务定义中:

    stdin_open: true
    tty: true

2
我一直在寻找一种从compose启动的容器中运行pdb的方法,现在终于找到了!请在需要的地方添加pdb行,使用-d选项启动compose,然后附加到所需的容器。 - Jack G
2
当你遇到断点时,要退出TTY,请按Ctrl+P,然后按Ctrl+Q不要使用Ctrl+C,它会终止进程。 - Varun Kumar
1
补充@Jonathan的答案,如果你在cmd中执行docker-compose up,那么只需在cmd中执行docker attach container_id即可。它会起作用。 - jeevu94
你是个保护屁股的人)))谢谢,兄弟 - undefined

20

pdb 需要一个可用的带有 TTY 终端。您可以通过告诉 Docker 在容器中附加一个交互式 TTY 到您的终端来轻松运行 pdb(使用 -it):

docker run -it foo

通常我还会添加 --rm 选项以删除我的临时容器。

docker run -it --rm foo

但在调试过程中,这并不总是最好的选择,因为容器在使用完毕后就被删除了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接