首页 > 解决方案 > 如何通过变量扩展将参数传递给 ENTRYPOINT?

问题描述

我正在构建一个基于我无法控制的其他图像的 docker 图像。基本图像通过简单地通过命令ENTRYPOINT传递参数来设置我想要使用的。CMD我还需要在参数中使用运行时变量扩展。这是我的 Dockerfile

FROM base # I do not control base, but I need to call its ENTRYPOINT.

# The "as default parameters to ENTRYPOINT" form. Does not expand variables.
CMD [ "--port", "$PORT" ]

# The "exec" from. I can't use it, because I do not know path to the executable as the base image is outside my control.
CMD [ "executable", "--port", "$PORT" ]

# The "shell" form. Won't even build because "--port" is interpreted as flag of "CMD".
CMD --port $PORT

如代码中所述,文档提供的三种形式均不适用于我的用例。

SO上已经有类似的问题,但都没有回答这个特定的用例。不包括变量扩展。而并没有说明无法更改ENTRYPOINT.

标签: docker

解决方案


在这种情况下,您不能使用CMD变量扩展。

Docker 本身不知道如何在容器命令中扩展变量。正如您所注意到的,有两种语法:

  1. CMD ["cmd", "$option"]从字面上传递cmd$option作为参数,根本没有扩展
  2. CMD cmd $option只是将该字符串包装在 shell 调用中,相当于CMD ["sh", "-c", "cmd $option"],并依赖于该 shell 来进行扩展。

在评论中,您提到了特定图像。如果您查看它生成的历史记录,它使用“容器即命令”模式,其中ENTRYPOINT是要启动的命令,而 是该命令的CMD参数。除非该命令特别希望接收sh-c作为选项,否则这是行不通的;但是sh -c包装器是 Docker 在启动时必须引起变量扩展的唯一方法。


您更具体地说是在尝试传递一个--port选项。这会影响容器内进程侦听的端口。由于容器在隔离的网络命名空间中运行,因此通常没有理由需要更改它:即使您有十几个容器都在侦听标准 HTTP 端口 80,它们也不会发生冲突。

如果你想从 Docker 外部连接到容器,你只需要更改docker run -p端口映射。同样,镜像文档建议启动镜像以docker run -p 8080:80使其可从主机端口 8080 访问;如果您想要不同的主机端口,请更改该号码,并保持第二个端口号相同。


推荐阅读