我是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。我怎么能做到这一点?
答案 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 dev
或1 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