我有一个带有使用ENV变量的ENTRYPOINT的Dockerfile。我无法使ENTRYPOINT结构化,因此容器也可以接受其他命令行参数。这是Dockerfile的相关部分:
ARG MODULE_NAME
ENV MODULE_NAME=$MODULE_NAME
ENTRYPOINT /usr/bin/python3 -m ${MODULE_NAME}
如果我只想启动不带其他参数的容器,那会很好:
docker run my-image
但是我需要能够将其他命令行参数(例如,“-debug”标志)传递给python进程,如下所示:
docker run my-image --debug
使用上面的ENTRYPOINT形式,“-debug” arg不会传递给python进程。我已经尝试了ENTRYPOINT的exec形式和shell形式,但是无法使其与ENV变量和命令行args一起使用。我尝试了其他几种形式:
这可以运行,但不接受其他参数:
ENTRYPOINT ["/bin/bash", "-c", "/usr/bin/python3 -m ${MODULE_NAME}"]
这给出了“/ usr / bin / python3:没有名为$ {MODULE_NAME}的模块”:
ENTRYPOINT ["/usr/bin/python3", "-m ${MODULE_NAME}"]
这给出了“/ usr / bin / python3:没有名为$ {MODULE_NAME}的模块”:
ENTRYPOINT ["/usr/bin/python3", "-m", "${MODULE_NAME}"]
最佳答案
似乎无法创建直接支持变量扩展和其他命令行参数的ENTRYPOINT。尽管ENTRYPOINT的shell形式将在运行时扩展ENV变量,但它不接受docker run
命令的其他(附加)参数。尽管ENTRYPOINT的exec形式确实支持其他命令行参数,但默认情况下它不会创建shell环境,因此ENV变量不会扩展。
为了解决这个问题,可以在exec表单中显式调用bash
来执行脚本,然后扩展ENV变量并将命令行args传递给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"]
泊坞窗镜像的输出:
$ docker run my-image
Args are ['/foo.py']
$ docker run my-image a b c
Args are ['/foo.py', 'a', 'b', 'c']
请注意,变量扩展在RUN命令期间发生(因为它们使用的是Shell形式),因此镜像中run_script.py的内容为:
/usr/bin/python3.5 -m foo $@
如果最终的RUN命令被替换为:
RUN echo "/usr/bin/python3.5 -m \$MODULE_NAME \$@" > /run_module.sh
那么run_script.sh将包含
/usr/bin/python3.5 -m $MODULE_NAME $@
但是正在运行的容器的输出将是相同的,因为变量扩展将在运行时发生。第二个版本的潜在好处是可以覆盖要在运行时运行的模块,而无需替换ENTRYPOINT。
关于python - 带有ENV变量和可选参数的Docker ENTRYPOINT,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49133234/