Jaa*_*aay 30 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运行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.我怎么能做到这一点?
Von*_*onC 52
确保您的Dockerfile声明环境变量有ENV:
ENV environment default_env_value
ENV cluster default_cluster_value
Run Code Online (Sandbox Code Playgroud)
的ENV <key> <value>形式可以内嵌替换.
然后,您可以使用docker run传递环境变量
docker run -p 9000:9000 -e environment=dev -e cluster=0 -d me/app
Run Code Online (Sandbox Code Playgroud)
或者您可以通过撰写文件设置它们:
node:
environment:
- environment=dev
- cluster=0
Run Code Online (Sandbox Code Playgroud)
您的Dockerfile CMD可以使用该环境变量,但是,如问题5509所述,您需要以下列sh -c形式执行此操作:
CMD ["sh", "-c", "node server.js ${cluster} ${environment}"]
Run Code Online (Sandbox Code Playgroud)
解释是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.
R0M*_*RMY 30
另一个选项是用于ENTRYPOINT指定node要运行的可执行文件并CMD提供参数.文档在Exec表单ENTRYPOINT示例中有一个示例.
使用这种方法,你的Dockerfile看起来像
FROM ...
ENTRYPOINT [ "node", "server.js" ]
CMD [ "0", "dev" ]
Run Code Online (Sandbox Code Playgroud)
在dev中运行它将使用相同的命令
docker run -p 9000:9000 -d me/app
Run Code Online (Sandbox Code Playgroud)
并在prod中运行它,您将参数传递给run命令
docker run -p 9000:9000 -d me/app 1 prod
Run Code Online (Sandbox Code Playgroud)
您可能希望CMD完全省略并始终传入0 dev或1 prod作为run命令的参数.这样你就不会意外地在dev中启动prod容器或者在prod中启动dev容器.
Bla*_*ack 16
选项 1) 使用 ENV 变量
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}
Run Code Online (Sandbox Code Playgroud)
Docker运行
$ docker run -d -p 9000:9000 -e ENVIRONMENT=dev -e CLUSTER=0 -me/app
Run Code Online (Sandbox Code Playgroud)
选项 2) 传递参数
Dockerfile
# use entrypoint instead of CMD and do not specify any arguments
ENTRYPOINT node server.js
Run Code Online (Sandbox Code Playgroud)
Docker运行
在 docker 镜像名称后传递参数
$ docker run -p 9000:9000 -d me/app 0 dev
Run Code Online (Sandbox Code Playgroud)
在 Docker 容器中执行此操作的典型方法是传入环境变量:
docker run -p 9000:9000 -e NODE_ENV=dev -e CLUSTER=0 -d me/app
Run Code Online (Sandbox Code Playgroud)
迟到才加入讨论。这是一个巧妙的技巧,您可以使用它来设置默认命令行参数,同时还支持使用自定义参数覆盖默认参数:
步骤#1 在你的 dockerfile 中调用你的程序,如下所示:
ENV DEFAULT_ARGS "--some-default-flag=123 --foo --bar"
CMD ["/bin/bash", "-c", "./my-nifty-executable ${ARGS:-${DEFAULT_ARGS}}"]
Run Code Online (Sandbox Code Playgroud)
步骤#2 现在什么时候可以像这样调用 docker-image:
# this will invoke it with DEFAULT_ARGS
docker run mydockerimage
# but this will invoke the docker image with custom arguments
docker run --env ARGS="--alternative-args --and-then-some=123" mydockerimage
Run Code Online (Sandbox Code Playgroud)
您还可以调整此技术以进行更复杂的论证评估,但您认为合适。Bash 支持多种单行结构来帮助您实现这一目标。
希望这项技术可以帮助一些人避免几个小时的头痛。
| 归档时间: |
|
| 查看次数: |
43196 次 |
| 最近记录: |