如何在 dockerfile 中传递 运行 时间参数?

How to pass run time arguments in dockerfile?

我正在尝试 docker 化我的 django 项目,以便 运行 使用 shell 中的 gunicorn 项目,我使用:

gunicorn --bind :8000 --workers $(( 2 * `cat /proc/cpuinfo | grep 'core id' | wc -l` + 1 )) MyQ.wsgi:application

效果很好, 我的想法是尽可能多地利用 gunicorn 文档中定义的内核。

$(( 2 * cat /proc/cpuinfo | grep 'core id' | wc -l + 1 )) 部分只是 returns 2*n+1,其中 n 是系统中的内核数量。

但是,我在将此命令重写为 Dockerfile 时遇到了一些问题,这是我目前的尝试:

CMD ["gunicorn", "--bind :8000", "--workers", "$(( 2 * `cat /proc/cpuinfo | grep 'core id' | wc -l` + 1 ))", "MyQ.wsgi:application"]

当我 运行 docker 运行:

时出现以下错误
gunicorn: error: argument -w/--workers: invalid int value: "$(( 2 * `cat /proc/cpuinfo | grep 'core id' | wc -l` + 1 ))"

所以基本上“$...”没有被评估,我不知道如何解决这个问题。

我认为最好在 Dockerfile 中使用 ENV 指令定义一个环境变量,然后在 CMD 指令中使用它。通过这种方式,您可以在从 Docker Image.

创建 Container 时设置环境变量

在你的 Dockerfile:

中像这样定义环境变量
ENV WORKERS 1

然后将您的 CMD 指令更改为:

CMD ["sh", "-c", "gunicorn --bind :8000 --workers $WORKERS MyQ.wsgi:application"]

最后,当您创建 Container 时,使用 -e 参数传递您的 WORKERS 环境变量。

CMD(以及ENTRYPOINTRUN)命令有两种形式。首选你写的表格:

CMD ["command_name", "--option", "value"]

但是,它不会 运行 和 shell 预处理命令行。例如,如果您 运行,

CMD ["ls", ">", "/host/directory/foo.ls"]

它会将 > 作为参数传递给程序,而不是执行 shell 重定向。

因此,为了使您的构造起作用,您需要使用另一种形式,它确实将其隐式包装在 shell 执行中 (/bin/sh -c '...')

CMD gunicorn --bind :8000 ...

在实践中,尝试通过 Dockerfile 强制 运行时间限制(例如工人计数)并不是您想要的;您应该允许在 docker run 命令或类似命令中指定此类内容。 @HassanMusavi 的回答更好。

Dockerfile 不支持 运行 时间参数(您想在 运行 宁 docker 文件时计算)。但是在您的情况下,您可以编写一个脚本 'test.sh',其中包含 gunicorn 的条目和参数。

并在 CMD 中定义脚本路径,如 CMD["test.sh"]。因此,当您从该图像创建容器时,它将 运行 容器中的脚本并将计算 $ expression 并在 运行 时间获取核心(即使 cat /proc/cpuinfo 将 运行 在你的容器中,但它会列出你的 docker 机器的核心)。这样你就不必依赖于计算核心并将其作为 -e 传递。