我们可以在DockerFile中将ARG传递给CMD吗?

我们可以在DockerFile中将ARG传递给CMD吗?,docker,docker-compose,dockerfile,Docker,Docker Compose,Dockerfile,如何在使用docker run命令时传递ENV变量?您能否告诉我在CMD中是否正确传递了ENV变量 我想实现的主要事情是,我已经在gitlab上上传了我的代码,并创建了一个docker映像,这样我就可以创建我的web应用程序容器。在这段代码中,我们有一个Core.js文件,它包含2个参数1。组织名称和端口号。为此,我需要运行node Core.js Org1 1401、node Core.js Org2 1402等。有一个通过docker文件拉入的shell脚本,我需要给出该文件的名称作为参数,

如何在使用docker run命令时传递ENV变量?您能否告诉我在CMD中是否正确传递了ENV变量

我想实现的主要事情是,我已经在gitlab上上传了我的代码,并创建了一个docker映像,这样我就可以创建我的web应用程序容器。在这段代码中,我们有一个Core.js文件,它包含2个参数1。组织名称和端口号。为此,我需要运行node Core.js Org1 1401、node Core.js Org2 1402等。有一个通过docker文件拉入的shell脚本,我需要给出该文件的名称作为参数,以便它应该使用相同的docker映像,但我可以为不同的组织创建多个容器

FROM alpine

LABEL MAINTAINER "CoE"
WORKDIR /

ARG proxy
ARG username
ARG pswd
ENV ORG_SCRIPT

RUN export http_proxy=$proxy                                                                    && \
    export https_proxy=$proxy                                                                   && \
    git clone -b master https://$username:$pswd@git.devops.company.net/dlr_ui         && \
    npm install                     

 EXPOSE 1401 1402 1403 1404 1405 1406 1407 1408
 WORKDIR /applications/package/ui_servers 
CMD ["sh","./${ORG_SCRIPT}"]    // It is not getting the script name over here. Can you tell if it is correct way or not. OR i should do:
CMD ["sh","./$ORG_SCRIPT"]

I'm getting error for both. Value is not coming to that variable.

Buid:
 docker build --no-cache --build-arg proxy=$http_proxy --build-arg username=dfadf--build-arg pswd=dsfadsf --build-arg -t uinodetest .


RUN:
docker run  -d -it -p 1401:1401 -e ORG_SCRIPT runOrg1.sh --name="Org1_UI" uinodetest

OR Other method i'm using is

FROM alpine

LABEL MAINTAINER "CoE"
WORKDIR /

ARG proxy
ARG username
ARG pswd
ENV ORG_NAME
ENV ORG_PORT

RUN export http_proxy=$proxy                                                                    && \
    export https_proxy=$proxy                                                                   && \
    git clone -b master https://$username:$pswd@git.devops.company.net/dlr_ui         && \
    npm install                     

 EXPOSE 1401 1402 1403 1404 1405 1406 1407 1408
 WORKDIR /applications/package/ui_servers 
CMD ["node","Core.js","$ORG_NAME","ORG_PORT"]



Buid:
 docker build --no-cache --build-arg proxy=$http_proxy --build-arg username=dfadf--build-arg pswd=dsfadsf --build-arg -t uinodetest .


RUN:
docker run  -d -it -p 1401:1401 -e ORG_NAME ORG1 -r ORG_PORT 1401 --name="Org1_UI" uinodetest

告诉我是否遗漏了什么或语法错误。

我认为更好的方法是使用
ENTRYPOINT
,然后添加
CMD
以执行
帮助
或类似操作

ENTRYPOINT ["node","Core.js"]
CMD ["--help"]
然后,当您启动容器时,将
$ORG\u NAME
$ORG\u PORT
传递给它。在这种情况下,docker将保留您的输入点,并将默认的
CMD
,即
--help
覆盖到您传递的其他选项,并确保将引号之间的命令作为单个命令处理

因此,在本例中,您将按以下方式运行容器:

docker run-it--name my_container myimage:latest“$ORG\u name$ORG\u PORT”
docker compose也可以实现同样的场景


这里有几个活动部件

对于需要配置的内容,在节点中使用
process.env
引用它们,而不是将它们作为命令行参数传递可能是最简单的。例如,在第二个示例中,请参考
process.env.ORG\u NAME

有些东西不需要配置。在第二个示例中,您可以为您的服务选择一个固定的TCP端口;即使使用Express默认端口3000,也可以
docker run-p 1401:3000
docker run-p 1402:3000
等将不同端口分配给运行同一映像的不同容器。在第一个示例中,您试图使用环境变量来指定整个命令;不用费心这么做,只需使用标准的Docker命令行即可

这会给你一个常规的Dockerfile,比如

来自节点:alpine
#通常不要在Dockerfile中使用“git克隆”。
WORKDIR/dlr\u用户界面
复制package.json package-lock.json/
运行npm安装
复制/
暴露3000
CMD[“node”,“Core.js”]
你根本不需要担心这个问题。你会像这样运行它

docker run -d -p 1401:3000 -e ORG_NAME=ORG1 --name="Org1_UI" uinodetest
CMD、ENTRYPOINT和RUN命令有两种语法。看起来像JSON数组(但实际上不是)的表单直接运行给定的命令,而不调用任何类型的shell、解释器或变量扩展。在第二个示例中,将使用文本字符串
$ORG\u NAME
ORG\u PORT
作为参数调用脚本。如果您只是编写一些看起来像命令的东西,而不是使用JSONish语法,那么它会自动包装在
sh-c

从语法上讲,我希望第一个示例能够满足您的要求(但请参见@BMitch的答案);但是直接传递命令会更简单

docker run -d -p 1401:1401 --name="Org1_UI" uinodetest ./runOrg1.sh

Docker将把环境变量传递给您的容器,但是您需要一个shell来将
${var}
语法解析到该变量中。你接近了:

CMD ["sh","./${ORG_SCRIPT}"]
我怀疑这不起作用的原因是传递给
sh
的arg尚未展开,而sh没有处理该arg,它只是在运行它。相反,您需要:

CMD ["sh","-c","./${ORG_SCRIPT}"]
这与string/shell语法几乎完全相同,我建议改为:

CMD ./${ORG_SCRIPT}

我已经创建了一个yaml文件版本:“2”服务:Uinode:image:uinodetest命令:sh./$testFile容器\u名称:ORG\u UI端口:-“1401:1401”环境:-FILE_NAME=$testFile并尝试通过shell运行脚本:env=$1 docker compose-f ui.yaml up-d并通过运行它。/test.sh uiOrg1.sh但它正在创建一个容器它将在几秒钟内退出,而不生成任何日志。如果没有任何错误且退出状态为
0
,则可能是因为脚本本身在完成执行目录后退出。换句话说,它应该在不退出的情况下运行,例如,当您运行
node index.js
时,除非您杀死进程,否则它不会退出。因此,我使用了forever start,但它仍然退出,并且脚本以nohup shp的形式运行,但我面临的问题是,它给出了错误:“./\${ORG\u script找不到它没有将值传递给此变量。感谢您的回答,它是以这种方式运行的,但如果在创建docker compose文件(即.yaml文件)并尝试运行它时,它将退出。我已创建了yaml文件版本:“2”服务:Uinode:image:uinodetest命令:sh./$testFile容器\u名称:ORG\u UI端口:-”1401:1401“环境:-FILE_NAME=$testFile并尝试通过shellscript运行:env=$1 docker compose-f ui.yaml up-d并通过./test.sh uiOrg1.sh运行它,但它正在创建一个容器,该容器将在几秒钟内退出,而不会生成任何日志。我使用了forever start,但它仍将退出,脚本将以nohup sh的形式运行