您拆分ENTRYPOINT 和CMD 的方式没有意义,并且无法在此处进行变量扩展。你应该把这两部分组合成一个CMD,然后使用shell形式运行它:
# no ENTRYPOINT
CMD python3 /usr/src/app/${CODEPATH}
(完成此操作后,最好还是使用@allan's answer 和直接docker run python-image python3 other-script-name.py 中的方法。)
Dockerfile 语法不允许在RUN、ENTRYPOINT 或CMD 命令中使用environment expansion。相反,这些命令有两种形式。
Exec form 要求您将命令格式化为 JSON 数组,并且不对您提供的内容进行任何处理;它使用一组确切的 shell 字和命令中的确切字符串运行命令。 Shell form 没有任何特殊语法,而是将命令包装在 sh -c 中,并且该 shell 处理您希望 shell 执行的所有正常操作。
以RUN为例:
# These are the same:
RUN ["ls", "-la", "some directory"]
RUN ls -la 'some directory'
# These are the same (and print a dollar sign):
RUN ["echo", "$FOO"]
RUN echo \$FOO
# These are the same (and a shell does variable expansion):
RUN echo $FOO
RUN ["/bin/sh", "-c", "echo $FOO"]
如果您同时拥有ENTRYPOINT 和CMD,则此扩展将分别针对每一半进行。这就是你遇到的分裂导致麻烦的地方:这些选项都不起作用:
# Docker doesn't expand variables at all in exec form
ENTRYPOINT ["python3"]
CMD ["/usr/src/app/${CODEPATH}"]
# ["python3", "/usr/src/app/${CODEPATH}"] with no expansion
# The "sh -c" wrapper gets interpreted as an argument to Python
ENTRYPOINT ["python3"]
CMD /usr/src/app/${CODEPATH}
# ["python3", "/bin/sh", "-c", "/usr/src/app/${CODEPATH}"]
# "sh -c" only takes one argument and ignores the rest
ENTRYPOINT python3
CMD ["/usr/src/app/${CODEPATH}"]
# ["/bin/sh", "-c", "python3", ...]
这个ENTRYPOINT/CMD拆分唯一真正的效果是制作一个只能运行Python脚本的容器,无需特殊配置(尴尬的docker run --entrypoint选项);您仍然在CMD 中提供大部分命令行,但不是全部。我倾向于建议将整个命令放入CMD,并将ENTRYPOINT 保留用于一些更专业的用途;还有一种将完整的命令放入ENTRYPOINT 并尝试使用CMD 部分来传递选项的模式。无论哪种方式,如果将整个命令放在一个指令或另一个指令中,事情会更好。