使用 docker run 命令将参数传递给 Dockerfile 中的 CMD [英] Use docker run command to pass arguments to CMD in Dockerfile

查看:96
本文介绍了使用 docker run 命令将参数传递给 Dockerfile 中的 CMD的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Docker 的新手,我很难按照自己的意愿设置 Docker 容器.我有一个 nodejs 应用程序在启动时可以接受两个参数.例如,我可以使用

node server.js 0 dev

node server.js 1 prod

在生产模式和开发模式之间切换并确定是否应该打开集群.现在我想用参数创建 docker 镜像来做类似的事情,到目前为止我唯一能做的就是调整 Dockerfile 以使其成为一行

CMD [ "node", "server.js", "0", "dev"]

docker build -t me/app . 构建docker.

然后 docker run -p 9000:9000 -d me/app 运行 docker.

但是如果我想切换到prod模式,我需要把Dockerfile的CMD改成

CMD [ "node", "server.js", "1", "prod"] ,

并且我需要杀死监听端口 9000 的旧镜像并重建镜像.我希望我能有像

这样的东西

docker run -p 9000:9000 environment=dev cluster=0 -d me/app

创建映像并使用environment"和cluster"参数运行 nodejs 命令,因此我不再需要更改 Dockerfile 并重建 docker.我怎样才能做到这一点?

解决方案

确保你的 Dockerfile 声明了一个环境变量 带有ENV:

ENV 环境 default_env_valueENV 集群 default_cluster_value

ENV <value> 表单可以被内联替换.

然后你可以使用docker run传递一个环境变量.请注意,每个变量都需要一个特定的 -e 标志才能运行.

docker run -p 9000:9000 -e environment=dev -e cluster=0 -d me/app

或者您可以通过您的撰写文件设置它们:

节点:环境:- 环境=开发- 集群=0

您的 Dockerfile CMD 可以使用该环境变量,但是,如 issue 5509,您需要以 sh -c 形式执行此操作:

CMD [sh"、-c"、node server.js ${cluster} ${environment}"]

<块引用>

解释是shell负责扩展环境变量,而不是Docker.当您使用 JSON 语法时,您明确要求您的命令绕过 shell 并直接执行.

Builder RUN 相同的想法(适用于 CMD 也是):

<块引用>

与 shell 形式不同,exec 形式不调用命令 shell.
这意味着正常的 shell 处理不会发生.

<块引用>

例如,RUN [ "echo", "$HOME";] 不会对 $HOME 进行变量替换.如果你想要 shell 处理,那么要么使用 shell 形式,要么直接执行 shell,例如: RUN [ "sh", "-c", "echo $HOME";].

<块引用>

当使用exec形式并直接执行shell时,就像shell形式一样,是shell在做环境变量扩展,而不是docker.

I'm new to Docker and I'm having a hard time to setup the docker container as I want. I have a nodejs app can take two parameters when start. For example, I can use

node server.js 0 dev

or

node server.js 1 prod

to switch between production mode and dev mode and determine if it should turn the cluster on. Now I want to create docker image with arguments to do the similar thing, the only thing I can do so far is to adjust the Dockerfile to have a line

CMD [ "node", "server.js", "0", "dev"]

and

docker build -t me/app . to build the docker.

Then docker run -p 9000:9000 -d me/app to run the docker.

But If I want to switch to prod mode, I need to change the Dockerfile CMD to be

CMD [ "node", "server.js", "1", "prod"] ,

and I need to kill the old one listening on port 9000 and rebuild the image. I wish I can have something like

docker run -p 9000:9000 environment=dev cluster=0 -d me/app

to create an image and run the nodejs command with "environment" and "cluster" arguments, so I don't need to change the Dockerfile and rebuild the docker any more. How can I accomplish this?

解决方案

Make sure your Dockerfile declares an environment variable with ENV:

ENV environment default_env_value
ENV cluster default_cluster_value

The ENV <key> <value> form can be replaced inline.

Then you can pass an environment variable with docker run. Note that each variable requires a specific -e flag to run.

docker run -p 9000:9000 -e environment=dev -e cluster=0 -d me/app

Or you can set them through your compose file:

node:
  environment:
    - environment=dev
    - cluster=0

Your Dockerfile CMD can use that environment variable, but, as mentioned in issue 5509, you need to do so in a sh -c form:

CMD ["sh", "-c", "node server.js ${cluster} ${environment}"]

The explanation is that the shell is responsible for expanding environment variables, not Docker. When you use the JSON syntax, you're explicitly requesting that your command bypass the shell and be executed directly.

Same idea with Builder RUN (applies to CMD as well):

Unlike the shell form, the exec form does not invoke a command shell.
This means that normal shell processing does not happen.

For example, RUN [ "echo", "$HOME" ] will not do variable substitution on $HOME. If you want shell processing then either use the shell form or execute a shell directly, for example: RUN [ "sh", "-c", "echo $HOME" ].

When using the exec form and executing a shell directly, as in the case for the shell form, it is the shell that is doing the environment variable expansion, not docker.

这篇关于使用 docker run 命令将参数传递给 Dockerfile 中的 CMD的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆