Docker-compose和pdb

79
我发现我不是第一个提出这个问题的人,但是没有清晰的答案:
如何在Python开发中使用docker-composer调试pdb?
当你向谷歌大叔询问django docker时,会得到很棒的docker-composer示例和教程,我有一个可用的环境 - 我可以运行docker-compose up并拥有一个整洁的开发环境,但是PDB不起作用(非常遗憾)。
我可以通过运行docker-compose run my-awesome-app python app.py 0.0.0.0:8000来解决,但是然后我无法从主机上访问我的应用程序http://127.0.0.1:8000(我可以使用docker-compose up),而且每次使用run都会创建新的容器,例如:dir_app_13dir_db_4,这完全不是我想要的。
好心人请帮忙。

PS
我在这个例子中使用pdb++,以及来自this django example的基本docker-compose.yml文件。我进行了一些实验,但似乎没有什么帮助。而且我正在使用docker-composer 1.3.0rc3,因为它支持指向Dockerfile。


这里的所有解决方案都对我无效。然而,这个使用remote-pdb的确有效。 - Akaisteph7
4个回答

153

使用以下步骤在任何Python脚本上附加pdb。

步骤1. 在您的yml文件中添加以下内容

stdin_open: true
tty: true
这将启用交互模式并附加标准输入。这相当于-it模式。 第2步。
docker attach <generated_containerid>

现在您将进入pdb shell


1
当我尝试使用 docker-compose up 启动所有容器时,这对我非常有效,谢谢。 - Nobilis
3
出现某些问题,这对我来说不起作用。我使用的是docker-compose 2.1版本。 - Divick
考虑到问题的表述方式,我很惊讶为什么这不是被接受的答案。它有一些小问题,但绝对做到了所要求的。 - Two-Bit Alchemist
5
第二步需要将其附加到容器ID,而不是实例ID,即您可以在执行“docker ps”命令时看到的ID之一。 - Mark Chackerian
这与 docker-compose up 结合使用效果完美。重要的是要注意,每次打开语句都会在第二个 shell 标签页中运行 docker attach <generated_container_id> 命令。 - Artur Barseghyan
2
第二步是这里最重要的部分。 - Shiplu Mokaddim

59
尝试使用--service-ports选项运行您的Web容器:docker-compose run --service-ports web

3
做到了!谢谢您,亲切的先生。 现在我正在使用docker-compose创建我的环境,并使用docker-compose run --rm --service-ports my-awesome-app python app.py 0.0.0.0:8000来运行我的服务或测试。再见,Vagrant! - McAbra
我在使用这个方法时遇到了一些问题。当我在pdb中输入内容时,我的终端是空白的。 - Jitu
你已经进入了pdb提示符,是吗?如果没有更多的信息,比如你正在使用什么框架、什么服务等等,我就不知道该怎么帮助你了。 - Jamey
我认为你可能也需要像-it这样的东西:请查看下面的答案。 - jpic
1
正如下面所指出的那样,没有理由避免使用 docker-compose up 来实现此功能。 - Two-Bit Alchemist
显示剩余4条评论

1
如果在添加之后
stdin_open: true
tty: true

你开始遇到类似的问题:
        fd = self._input_fileno()
        if fd is not None and fd in ready:
>           return ord(os.read(fd, 1))
E           TypeError: ord() expected a character, but string of length 0 found

您可以尝试在Docker文件的顶部添加ENV LC_ALL en_US.UTF-8

FROM python:3.8.2-slim-buster as build_base
ENV LC_ALL en_US.UTF-8


0
在我的经验中,docker-compose up命令不会提供交互式 shell,但它会将 STDOUT 输出到默认的只读 shell。
或者,如果您已指定并映射日志目录,则docker-compose up命令将不会在附加的 shell 上打印任何内容,而是将输出发送到您映射的日志。因此,一旦运行,您必须单独连接容器。
当您执行docker-compose up时,请通过-d使其进入分离模式,例如docker-compose up -d,然后通过以下方式连接到容器: docker exec -it your_container_name bash

你好,能否指出您对我的回答进行负评的原因?这将有助于我改进自己并纠正错误。谢谢! - Bhuro
1
exec 命令可以让你进入正在运行的容器内部的 shell,使用 -it 参数可以实现交互式操作,但是你不会连接到正在运行的应用程序,因此无法连接到 pdb 的标准输入/输出。正确的方法是让 compose 启动带有 stdin 和 tty 的服务,然后附加到该进程(以使 stdin 正常工作)。 - Cyrille Pontvieux
明白了,......这就像我们尝试使用exec时启动另一个实例一样,......虽然对于PDB,我有一个更好的选择,那就是基于Web的,并且在Docker上运行得非常出色......https://github.com/Kozea/wdb#docker - Bhuro

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