将多个文件添加到 docker 但只有 运行 其中一个

ADD multiple Files to a docker but just RUN one of them

这只是一个理论问题。有没有办法 运行 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

这没有什么“理论上的”。 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,如果它正是 shebang line 上的内容。)

在 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()

现在在您的 Docker 文件中,您可以使用通用 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

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