【问题标题】:ADD multiple Files to a docker but just RUN one of them将多个文件添加到泊坞窗,但只运行其中一个
【发布时间】:2022-01-14 06:18:53
【问题描述】:

这只是一个理论问题。有没有办法运行 docker 但只运行一个特定的脚本而不更改 Dockerfile?也许使用docker run [container] 命令?

Dockerfile:

FROM python:3.8

ADD main1.py
ADD main2.py
ADD main3.py
ADD main4.py
ADD main5.py

理论指挥:

docker run docker-test main2.py

【问题讨论】:

  • 这应该和你描述的完全一样。我仍然会在图像中设置一些默认的CMD(并且通常更喜欢COPY 而不是ADD,除非您想下载 URL 或解压缩存档文件)。试一试有用吗?
  • @DavidMaze 我现在这样试了: Dockerfile FROM python:3.8 ADD main.py . ADD main1.py . ADD main2.py . ADD main3.py . CMD [ "python", "./main.py" ] 我运行的命令: docker build -t docker-test . docker run docker-test main1.py 错误 docker:来自守护进程的错误响应:OCI 运行时创建失败:container_linux.go:380:启动容器进程导致:exec:“main1.py”:可执行文件在 $PATH 中找不到文件:未知。 ERRO[0001] 错误等待容器:上下文取消
  • 你可以尝试docker run ... ./main3.py,或者在Dockerfile中设置ENV PATH,这样正常的路径查找就可以找到脚本。还要确保脚本是可执行的(在主机上运行chmod +x main*.py 应该带入映像)并且它们以“shebang”行#!/usr/bin/env python3 开头。这应该与直接在主机上运行脚本所需的操作相同,无需 Docker。
  • docker run docker-test ./main3.py 给出与上述相同的错误。如果你有一些空闲时间,你能给我完整的命令/Dockerfiles 到你给出的提示吗?我是 Ubuntu cmd 和 docker 新手,所以我不知道如何设置您的建议

标签: python docker dockerfile docker-container


【解决方案1】:

这没有什么“理论上的”。 Docker 将文件复制到适当的位置,如果它们正在运行的可执行文件,您可以使用docker run image executable 执行它们...但是

  • 它要求文件可以正确执行(或者您需要明确地说docker run image python executable 才能运行不可执行的 Python 脚本)

  • 它要求文件在您的PATH 中,以便您能够在没有路径的情况下指定它们的名称;或者您需要指定容器内的完整路径,或者可能是相对路径(./executable,如果它们位于容器的默认工作目录中)

    docker run image /path/to/executable
    
  • 您显然需要容器在其PATH 中包含python 才能找到python;或者您同样需要指定解释器的完整路径

    docker run image /usr/bin/python3 /path/to/executable
    

总之,可能要确保您有 chmod +x 脚本文件,并且它们的第一行包含(道德上等同于)#!/usr/bin/env python3(或 python,如果这是二进制文件的名称)。

(显然,不要在您希望能够在 Linux 容器中执行的文件中使用 DOS 换行符。Python 可以应付,但 Linux 内核会寻找 /usr/bin/env python3^M,如果这正是它在 @ 上所说的987654321@.)

【讨论】:

    【解决方案2】:

    在 Python 应用程序的特定情况下,标准 Python setuptools 包具有一些可以简化此操作的功能。

    在您的应用程序的 setup.cfg 文件中,您可以声明 entry points(与名称相似的 Docker 概念不同),它提供简单的脚本来启动您的应用程序的特定部分。

    [options.entry_points]
    console_scripts =
      main1 = app.main1:main
      main2 = app.main2:main
    

    脚本 app/main1.py 看起来像普通的顶级 Python 脚本

    #!/usr/bin/env python3
    
    # the console_scripts call this directly
    def main():
      ...
    
    # for interactive use
    if __name__ == '__main__':
      main()
    

    现在在您的 Dockerfile 中,您可以使用通用 Python 应用程序配方并安装它;所有console_scripts 将在标准$PATH 中自动可见。

    FROM python:3.8
    WORKDIR /app
    COPY . .
    RUN pip install .
    CMD ["main1"]
    
    docker run --rm my-image main2
    

    值得注意的是,直到上一部分,我们一直在使用通用的 Python 实用程序,并且您可以在没有 Docker 的情况下做同样的事情

    # directly on the host, without Docker
    python3 -m venv ./virtual_environment
    . ./virtual_environment/bin/activate
    pip install .
    
    # then run any of the scripts directly
    main3
    
    # technically activating the virtual environment is optional
    deactivate
    ./virtual_environment/bin/main4
    

    这里的基本点是相同的规则适用于在主机上运行命令,在 Dockerfile CMDdocker run 命令覆盖(必须在 $PATH,可执行,具有正确的解释器,)。请参阅@tripleee's answer 了解更通用、非 Python 特定的方法。

    【讨论】:

      猜你喜欢
      • 2019-01-15
      • 1970-01-01
      • 2019-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-22
      • 1970-01-01
      相关资源
      最近更新 更多