如何在 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
(以及ENTRYPOINT
和RUN
)命令有两种形式。首选你写的表格:
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 传递。
我正在尝试 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
(以及ENTRYPOINT
和RUN
)命令有两种形式。首选你写的表格:
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 传递。