使用docker run命令将参数传递给Dockerfile中的CMD

时间:2016-11-29 18:29:03

标签: node.js docker dockerfile

我是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 run -p 9000:9000 -d me/app运行泊坞窗。

但如果我想切换到prod模式,我需要将Dockerfile CMD更改为

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

我需要杀死侦听端口9000的旧版本并重建图像。 我希望我能有像

这样的东西

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

创建一个图像并使用" environment"运行nodejs命令和"集群"参数,所以我不需要更改Dockerfile并重建docker。我怎么能做到这一点?

5 个答案:

答案 0 :(得分:40)

确保您的Dockerfile声明了一个环境变量with ENV

ENV environment default_env_value
ENV cluster default_cluster_value

ENV <key> <value>表单可以是replaced inline

然后你可以pass an environment variable with docker run

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

或者你可以set them through your compose file

node:
  environment:
    - environment=dev
    - cluster=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。

答案 1 :(得分:27)

另一种选择是使用ENTRYPOINT指定node是要运行的可执行文件,CMD来提供参数。文档在Exec form ENTRYPOINT example中有一个示例。

使用这种方法,您的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 dev1 prod作为参数传递给run命令。这样你就不会意外地在dev中启动prod容器或者在prod中启动dev容器。

答案 2 :(得分:4)

在Docker容器中执行此操作的典型方法是传入环境变量:

docker run -p 9000:9000 -e NODE_ENV=dev -e CLUSTER=0 -d me/app

答案 3 :(得分:1)

与主题无关,存在构建参数,可让您在构建时传递表现为环境变量的参数,以供您在Docker映像构建过程中使用:

#!/bin/bash

if [ $UID -eq 0 ]; then
  sudo chmod 777 "$0"
  exec su ec2-user "$0"
fi

答案 4 :(得分:0)

选项1)使用ENV变量

Dockerfile

x[0]

Docker运行

# we need to specify default values
ENV ENVIRONMENT=production
ENV CLUSTER=1

# there is no need to use parameters array
CMD node server.js ${CLUSTER} ${ENVIRONMENT}

选项2)传递参数

Dockerfile

$ docker run -d -p 9000:9000 -e ENVIRONMENT=dev -e CLUSTER=0 -me/app

Docker运行

在docker映像名称后传递参数

# use entrypoint instead of CMD and do not specify any arguments
ENTRYPOINT node server.js