无法通过 ssh 和 python 的子进程模块运行 Docker 命令

发布于 2025-01-09 20:03:42 字数 929 浏览 0 评论 0原文

我正在尝试使用 subprocess 模块自动运行 docker build 命令,如下所示:

command = "docker build -t image_name ."

ssh_command = "ssh -o 'StrictHostKeyChecking=no' -i 'XXXXX.pem' ubuntu@" + cur_public_ip + " " + command

retval = subprocess.run(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)

if retval.stderr != '':
    print('Error trace: ')
    print(retval.stderr)
else:
    print("Docker image succesfully built.")
    print(retval.stdout)

有趣的是,如果我在手动 SSH 到我的 ec2 实例后运行此命令(作为命令变量的字符串),它可以正常工作。

但是当我运行上面的代码时,我收到此错误:

Error trace: 
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

我似乎无法解决这个问题,并且我陷入了困境,因为我不明白我所做的与手动 sshing 进入实例并运行命令有什么不同。

docker 守护进程肯定正在运行,因为我可以通过 ssh 终端手动构建。我尝试更改 Dockerfile 和 ec2 实例上所有相关文件的 rwx 权限,但这也没有帮助。

我该如何进行这项工作?我需要以编程方式能够做到这一点。

谢谢。

I am trying to automatically run a docker build command using the subprocess module as such:

command = "docker build -t image_name ."

ssh_command = "ssh -o 'StrictHostKeyChecking=no' -i 'XXXXX.pem' ubuntu@" + cur_public_ip + " " + command

retval = subprocess.run(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)

if retval.stderr != '':
    print('Error trace: ')
    print(retval.stderr)
else:
    print("Docker image succesfully built.")
    print(retval.stdout)

Interestingly, if I run this command (the string that is the command variable) after I manually SSH into my ec2 instance, it works fine.

But when I run the code above, I get this error:

Error trace: 
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

I can't seem to solve this problem, and I am stuck since I don't see how what I am doing is different from manually sshing into the instance and running the command.

The docker daemon is definitely running since I can build manually through an ssh terminal. I've tried changing the rwx permissions of the Dockerfile and all related files on the ec2 instance, but that did not help as well.

How do I make this work? I need to programmatically be able to do this.

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

尘曦 2025-01-16 20:03:42

您的第一个问题是您仅将 command 传递给 subprocess.run,因此您在本地运行 docker build

                        +--- look here
                        |
                        v
retval = subprocess.run(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)

您的第二个问题是您在 ssh_command 中进行了大量引用,这将导致许多问题。例如,正如所写,您将文字字符串'StrictHostKeyChecking=no'传递给ssh,导致如下错误:

command-line: line 0: Bad configuration option: 'stricthostkeychecking

因为您不是通过 shell 执行命令,所有这些引号都将在命令行中逐字传递。

您最好将命令构建为列表,而不是调用 command.split(" "),如下所示:

import subprocess

cur_public_ip = "1.2.3.4"
command = ["docker", "build", "-t", "image_name", "."]

ssh_command = [
    "ssh",
    "-o",
    "stricthostkeychecking=no",
    "-i",
    "XXXXX.pem",
    f"ubuntu@{cur_public_ip}",
] + command

retval = subprocess.run(
    ssh_command,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
    universal_newlines=True,
)

Your first problem is that you're only passing command to subprocess.run, so you're running docker build locally:

                        +--- look here
                        |
                        v
retval = subprocess.run(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)

Your second problem is that you've got way to much quoting going on in ssh_command, which is going to result in a number of problems. As written, for example, you'll be passing the literal string 'StrictHostKeyChecking=no' to ssh, resulting in an error like:

command-line: line 0: Bad configuration option: 'stricthostkeychecking

Because you're not executing your command via a shell, all of those quotes will be passed literally in the command line.

Rather than calling command.split(" "), you would be better off just building the command as a list, something like this:

import subprocess

cur_public_ip = "1.2.3.4"
command = ["docker", "build", "-t", "image_name", "."]

ssh_command = [
    "ssh",
    "-o",
    "stricthostkeychecking=no",
    "-i",
    "XXXXX.pem",
    f"ubuntu@{cur_public_ip}",
] + command

retval = subprocess.run(
    ssh_command,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
    universal_newlines=True,
)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文