如何使用Python启动一个交互式的Docker容器?

6

我正在使用Docker镜像,并以交互模式启动它,命令如下:docker run -it --rm ubuntu bash

实际上,我使用的镜像有许多复杂的参数,这就是为什么我编写脚本来构建完整的docker run命令并为我启动它。随着逻辑越来越复杂,我想将脚本从bash迁移到Python。

使用docker-py,我准备好了运行镜像所需的一切。然而,似乎不支持使用docker.containers.run进行交互式 shell,(详情请参考此处)。因此,使用subprocess替代似乎是合理的,因此我尝试了以下内容:

import subprocess

subprocess.Popen(['docker', 'run', '-it', '--rm', 'ubuntu', 'bash'])

但这会给我带来:
$ python3 docker_run_test.py 
$ unable to setup input stream: unable to set IO streams as raw terminal: input/output error
$

请注意,错误消息会出现在与python命令不同的shell提示符中。
如何使“python3 docker_run_test.py”执行与“docker run -it --rm ubuntu bash”等效的操作?

这对于子进程来说太复杂了。Packer是用于自动化Docker任务的软件包。 - postoronnim
1
如果您的意图是启动多个Docker容器并一次性停止它们,那么Docker Compose可能是您要寻找的。但是,如果您希望继续使用Python,则可能需要pty - thuyein
当前的答案都添加了一个不必要的要求,即需要安装docker cli,而docker-py可以正确地与远程主机通信,而无需在您的计算机上安装docker-cli。 - sorin
2个回答

2

我们可以使用这个吗?

import os
os.system('docker run -it --rm ubuntu bash')

2
您可以使用伪终端来读取和写入容器进程。
import pty
import sys
import select
import os
import subprocess

pty, tty = pty.openpty()

p = subprocess.Popen(['docker', 'run', '-it', '--rm', 'ubuntu', 'bash'], stdin=tty, stdout=tty, stderr=tty)

while p.poll() is None:
    # Watch two files, STDIN of your Python process and the pseudo terminal
    r, _, _ = select.select([sys.stdin, pty], [], [])
    if sys.stdin in r:
        input_from_your_terminal = os.read(sys.stdin.fileno(), 10240)
        os.write(pty, input_from_your_terminal)
    elif pty in r:
        output_from_docker = os.read(pty, 10240)
        os.write(sys.stdout.fileno(), output_from_docker)

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