如何在python脚本中创建docker容器,在容器中运行python脚本?

问题描述 投票:0回答:1

我正在创建一个类似于leetcode的网站,用户可以在其中提交代码。我将在 Docker 容器中运行此代码以采取安全措施。我的代码的行为不符合我的预期。我编写了这个显示问题的脚本。我也在 m1 macbook 上执行此操作。

预期行为:

  • 打印当前目录的内容
  • 创建一个 docker 容器并将 test_file.py 从当前目录复制到其中。
  • 运行 test_file.py 并将容器的标准输出打印到我的控制台。

发生了什么:

  • 打印当前目录的内容(包括test_file.py)
  • Docker 找不到 test_file.py

main.py:

import subprocess

dockerfile_content = f"""
FROM python:3.9-slim

WORKDIR /app

COPY ./test_file.py /app/test_file.py

CMD ["python", "app/test_file.py"]
"""

# Docker image and container names
image_name = 'image_name'
container_name = 'conainer_name'

# Build the Docker image
subprocess.run(['ls'])
build_process = subprocess.Popen(['docker', 'build', '-t', image_name, "-"], stdin=subprocess.PIPE)
build_process.communicate(input=dockerfile_content.encode())

# Run the Docker container
result = subprocess.run(['docker', 'run', '--name', container_name, image_name], capture_output=True, text=True)
print('STDOUT:', result.stdout)
print('STDERR:', result.stderr)

# Clean up: remove container and image
subprocess.run(['docker', 'rm', container_name], check=False)
subprocess.run(['docker', 'rmi', image_name], check=False)

输出:

test_file.py main.py
+] Building 1.1s (7/7) FINISHED                                                                                   docker:desktop-linux
 => [internal] load build definition from Dockerfile                                                                               0.0s
 => => transferring dockerfile: 148B                                                                                               0.0s
 => [internal] load metadata for docker.io/library/python:3.9-slim                                                                 1.1s
 => [internal] load .dockerignore                                                                                                  0.0s
 => => transferring context: 2B                                                                                                    0.0s
 => [1/3] FROM docker.io/library/python:3.9-slim@sha256:d3185e5aa645a4ff0b52416af05c8465d93791e49c5a0d0f565c119099f26cde           0.0s
 => => resolve docker.io/library/python:3.9-slim@sha256:d3185e5aa645a4ff0b52416af05c8465d93791e49c5a0d0f565c119099f26cde           0.0s
 => [internal] load build context                                                                                                  0.0s
 => => transferring context: 2B                                                                                                    0.0s
 => CACHED [2/3] WORKDIR /app                                                                                                      0.0s
 => ERROR [3/3] COPY ./test_file.py /app/test_file.py                                                                              0.0s
------
 > [3/3] COPY ./test_file.py /app/test_file.py:
------
Dockerfile:6
--------------------
   4 |     WORKDIR /app
   5 |     
   6 | >>> COPY ./test_file.py /app/test_file.py
   7 |     
   8 |     CMD ["python", "app/test_file.py"]
--------------------
ERROR: failed to solve: failed to compute cache key: failed to calculate checksum of ref d7cab07d-c12c-40fd-80e6-5ccd8b3c75df::nufuebj2yhxnpjfnizar2q5go: "/test_file.py": not found
STDOUT: 
STDERR: Unable to find image 'image_name:latest' locally
docker: Error response from daemon: pull access denied for image_name, repository does not exist or may require 'docker login': denied: requested access to the resource is denied.
See 'docker run --help'.

Error response from daemon: No such container: conainer_name
Error response from daemon: No such image: image_name:latest
python docker subprocess
1个回答
0
投票

当您运行

docker build
时,您将其调用为
docker build -
。 这需要标准输入上的 Dockerfile,但它无法访问任何文件系统内容;没有可以
COPY
插入图像的文件。

如果源文件位于当前目录中,则应将当前目录

.
作为构建上下文参数传递。 在这种情况下,您没有将任何内容传递给标准输入。

subprocess.run(['docker', 'build', '-t', image_name, "."], check=True)

我在这里做了一些更改。 我已更改为

subprocess.run()
来执行阻止呼叫。 我已将最后一个参数从
-
更改为
.
,以传递当前目录。 我还在末尾添加了
check=True
,因此如果映像构建失败,您的 Python 代码将因异常而停止。

您可以传递任何目录作为最后一个参数,因此您也可以使用

tempfile.TemporaryDirectory
。 如果您使用 Docker SDK for Python 而不是尝试使用
subprocess
来调用 Docker CLI,您的系统可能会更加健壮;这将让您可以执行诸如以编程方式获取匿名图像和容器的 ID 之类的操作,而无需解析
docker
CLI 输出。

© www.soinside.com 2019 - 2024. All rights reserved.