具有ENV变量和可选参数的Docker ENTRYPOINT

bog*_*ron 9 python docker dockerfile

我有一个带有ENTRYPOINT的Dockerfile,它使用一个ENV变量.我无法获得ENTRYPOINT结构,因此容器也可以接受其他命令行参数.这是Dockerfile的相关部分:

ARG MODULE_NAME
ENV MODULE_NAME=$MODULE_NAME
ENTRYPOINT /usr/bin/python3 -m ${MODULE_NAME}
Run Code Online (Sandbox Code Playgroud)

如果我只想在没有其他参数的情况下启动容器,那就可以正常工作:

docker run my-image
Run Code Online (Sandbox Code Playgroud)

但我需要能够将其他命令行参数(例如," - debug"标志)传递给python进程,如下所示:

docker run my-image --debug
Run Code Online (Sandbox Code Playgroud)

使用上面的ENTRYPOINT形式," - debug"arg不会传递给python进程.我已经尝试了ENTRYPOINT的exec形式和shell形式,但无法使它与ENV变量命令行args一起使用.我试过的其他几种形式:

这会运行,但不接受其他参数:

ENTRYPOINT ["/bin/bash", "-c", "/usr/bin/python3 -m ${MODULE_NAME}"]
Run Code Online (Sandbox Code Playgroud)

这给出了"/ usr/bin/python3:没有名为$ {MODULE_NAME}的模块":

ENTRYPOINT ["/usr/bin/python3", "-m ${MODULE_NAME}"]
Run Code Online (Sandbox Code Playgroud)

这给出了"/ usr/bin/python3:没有名为$ {MODULE_NAME}的模块":

ENTRYPOINT ["/usr/bin/python3", "-m", "${MODULE_NAME}"]
Run Code Online (Sandbox Code Playgroud)

bog*_*ron 9

看来无法创建直接支持变量扩展其他命令行参数的ENTRYPOINT .虽然ENTRYPOINT的shell形式将在运行时扩展ENV变量,但它不接受docker run命令中的附加(附加)参数.虽然ENTRYPOINT的exec形式确实支持其他命令行参数,但默认情况下它不会创建shell环境,因此不会展开ENV变量.

为了解决这个问题,bash可以在exec表单中显式调用它来执行一个脚本,然后扩展ENV变量并将命令行参数传递给python进程.这是一个示例Dockerfile,它执行此操作:

FROM ubuntu:16.04
ARG MODULE_NAME=foo
ENV MODULE_NAME=${MODULE_NAME}

RUN apt-get update -y && apt-get install -y python3.5

# Create the module to be run
RUN echo "import sys; print('Args are', sys.argv)" > /foo.py

# Create a script to pass command line args to python
RUN echo "/usr/bin/python3.5 -m $MODULE_NAME \$@" > /run_module.sh

ENTRYPOINT ["/bin/bash", "/run_module.sh"]
Run Code Online (Sandbox Code Playgroud)

来自docker镜像的输出:

$ docker run my-image
Args are ['/foo.py']

$ docker run my-image a b c
Args are ['/foo.py', 'a', 'b', 'c']
Run Code Online (Sandbox Code Playgroud)

请注意,在RUN命令期间发生变量扩展(因为它们使用shell形式),因此图像中run_script.py的内容为:

/usr/bin/python3.5 -m foo $@
Run Code Online (Sandbox Code Playgroud)

如果最终的RUN命令被替换为:

    RUN echo "/usr/bin/python3.5 -m \$MODULE_NAME \$@" > /run_module.sh
Run Code Online (Sandbox Code Playgroud)

然后run_script.sh将包含

/usr/bin/python3.5 -m $MODULE_NAME $@
Run Code Online (Sandbox Code Playgroud)

但是,运行容器的输出将是相同的,因为变量扩展将在运行时发生.第二个版本的潜在好处是可以覆盖要在运行时运行的模块而无需替换ENTRYPOINT.