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

Node.js 使用docker run命令将参数传递给Dockerfile中的CMD,node.js,docker,dockerfile,Node.js,Docker,Dockerfile,我是Docker的新手,我很难按照自己的意愿设置Docker容器。我有一个nodejs应用程序可以采取两个参数时启动。例如,我可以使用 node server.js 0 dev 或 node server.js 1产品 在生产模式和开发模式之间切换,并确定是否应打开集群。现在我想用参数创建docker图像来做类似的事情,到目前为止我唯一能做的就是调整docker文件,使其有一行 CMD[“node”、“server.js”、“0”、“dev”] 及 docker build-t me/app.构

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

node server.js 0 dev

node server.js 1产品

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

CMD[“node”、“server.js”、“0”、“dev”]

docker build-t me/app.
构建docker

然后
docker run-p9000:9000-dme/app
运行docker

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

CMD[“node”、“server.js”、“1”、“prod”]

我需要杀死在端口9000上监听的那个老家伙并重建图像。 我希望我能有像这样的东西

docker run-p 9000:9000环境=dev集群=0-d me/app


创建一个映像并使用“environment”和“cluster”参数运行nodejs命令,这样我就不需要再更改Dockerfile和重建docker了。如何实现这一点?

在Docker容器中实现这一点的典型方法是传入环境变量:

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

确保Dockerfile声明了一个环境变量:

ENV
表单可以是

那你就可以了。请注意,每个变量都需要一个特定的
-e
标志才能运行

docker run-p 9000:9000-e environment=dev-e cluster=0-d me/app
或者你可以:

节点:
环境:
-环境=开发
-群集=0
Dockerfile
CMD
可以使用该环境变量,但是,如中所述,您需要以
sh-c
的形式执行此操作:

CMD ["sh", "-c", "node server.js ${cluster} ${environment}"]
解释是shell负责扩展环境变量,而不是Docker。当您使用JSON语法时,明确要求您的命令绕过shell并直接执行

与(同样适用于
CMD
)相同的想法:

与shell表单不同,exec表单不调用命令shell。
这意味着正常的shell处理不会发生

例如,
RUN[“echo”,“$HOME”]
不会对
$HOME
执行变量替换。如果需要shell处理,则可以使用shell表单或直接执行shell,例如:
RUN[“sh”、“-c”、“echo$HOME”]

当使用exec表单并直接执行shell时,就像shell表单一样,执行环境变量扩展的是shell,而不是docker

另一个选项是用于指定
节点
是要运行的可执行文件并提供参数。文档中有一个示例

使用这种方法,Dockerfile看起来像

FROM ...

ENTRYPOINT [ "node",  "server.js" ]
CMD [ "0", "dev" ]
在dev中运行它将使用相同的命令

docker run -p 9000:9000 -d me/app
在prod中运行它,您将把参数传递给run命令

docker run -p 9000:9000 -d me/app 1 prod


您可能希望完全省略
CMD
,并始终将
0 dev
1 prod
作为参数传递给run命令。这样,您就不会意外地启动dev中的prod容器或prod中的dev容器。

有点离题了,构建参数的存在允许您在构建时传入参数,这些参数作为环境变量在docker映像构建过程中使用:

$ docker build --build-arg HTTP_PROXY=http://10.20.30.2:1234 .
选项1)使用环境变量

Dockerfile

# 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}
# use entrypoint instead of CMD and do not specify any arguments
ENTRYPOINT node server.js
码头工人赛跑

$ docker run -d -p 9000:9000 -e ENVIRONMENT=dev -e CLUSTER=0 -me/app
选项2)传递参数

Dockerfile

# 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}
# use entrypoint instead of CMD and do not specify any arguments
ENTRYPOINT node server.js
码头工人赛跑

$ docker run -d -p 9000:9000 -e ENVIRONMENT=dev -e CLUSTER=0 -me/app
在docker映像名称后传递参数

$ docker run -p 9000:9000 -d me/app 0 dev

我如何在docker文件CMD中使用ENV,你能给我一个例子吗?@Jaaaaaaay
ENV
是你的
Dockerfile
(read)中的一个声明,然后由
docker run-e myvar=myvalue