使用docker run命令将parameter passing给Dockerfile中的CMD
我是Docker的新手,我很难按照自己的意愿设置Docker容器。 我有一个nodejs应用程序可以采取两个参数,当启动。 例如,我可以使用
node server.js 0 dev
要么
node server.js 1 prod
在生产模式和开发模式之间切换,并确定是否应打开群集。 现在我想用参数创builddocker映像来做类似的事情,我目前唯一能做的事情就是调整Dockerfile来创build一个行
CMD [ "node", "server.js", "0", "dev"]
和
docker build -t me/app .
build造docker。
然后docker run -p 9000:9000 -d me/app
来运行docker。
但是,如果我想切换到prod模式,我需要将Dockerfile CMD更改为
CMD [ "node", "server.js", "1", "prod"]
,
我需要杀掉在9000端口听的老人并重build图像。 我希望我能有类似的东西
docker run -p 9000:9000 environment=dev cluster=0 -d me/app
创build一个映像并运行带有“environment”和“cluster”参数的nodejs命令,所以我不需要更改Dockerfile并重新构builddocker。 我怎样才能做到这一点?
确保你的Dockerfile 用ENV
声明一个环境variables:
ENV environment default_env_value ENV cluster default_cluster_value
可以内联replace ENV <key> <value>
表单。
然后你可以通过docker run来传递一个环境variables
docker run -p 9000:9000 -e environment=dev -e cluster=0 -d me/app
或者你可以通过你的撰写文件来设置它们 :
node: environment: - environment=dev - cluster=0
您的Dockerfile CMD
可以使用该环境variables,但是,如问题5509中所述 ,您需要以sh -c
格式执行此操作:
CMD ["sh", "-c", "node server.js ${cluster} ${environment}"]
解释是shell负责扩展环境variables,而不是Docker。 当您使用JSON语法时 ,您明确要求您的命令绕过shell并直接执行。
与Builder RUN相同的想法(也适用于CMD
):
与shellforms不同,execforms不会调用命令shell。
这意味着正常的shell处理不会发生。例如,
RUN [ "echo", "$HOME" ]
不会在$HOME
上进行variablesreplace。 如果你想要shell处理,那么使用shellforms或者直接执行一个shell,例如:RUN [ "sh", "-c", "echo $HOME" ]
。当使用exec表单并直接执行一个shell时,就像在shell表单的情况下一样,shell是在执行环境variables扩展,而不是docker。
另一个select是使用ENTRYPOINT
指定该node
是可运行的可执行文件, CMD
提供参数。 这个文档在Exec form ENTRYPOINT示例中有一个例子 。
使用这种方法,你的Dockerfile看起来就像这样
FROM ... ENTRYPOINT [ "node", "server.js" ] CMD [ "0", "dev" ]
在dev中运行它将使用相同的命令
docker run -p 9000:9000 -d me/app
并运行它prod你会传递参数到运行命令
docker run -p 9000:9000 -d me/app 1 prod
您可能希望完全忽略CMD
并始终将0 dev
或1 prod
作为parameter passing给run命令。 这样你就不会不小心在产品的开发或开发容器中启动产品容器。
在Docker容器中这样做的典型方式是传入环境variables:
docker run -p 9000:9000 -e NODE_ENV=dev -e CLUSTER=0 -d me/app