Reputation: 662
How can i pass ENV variable while using docker run command and also Can you tell me if i'm passing the ENV variable correctly in CMD?
Main thing which i want to achieve is that I have uploaded my code on gitlab and creating a docker image so that i can create my web application container. In that code we have a file Core.js which takes 2 arguments 1. Organization name and Port number. For that i need to run node Core.js Org1 1401, node Core.js Org2 1402, etc. There is a shell script which is pulled in via docker file i need to give name of that file as an argument so that it should use same docker image but i can create multiple container for different organization
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:[email protected]/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:[email protected]/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
Tell me if i'm missing something or my syntax is wrong.
Upvotes: 2
Views: 13146
Reputation: 11940
I think a better approach would be using ENTRYPOINT
and then add CMD
to execute help
or something similar
ENTRYPOINT ["node","Core.js"]
CMD ["--help"]
Then when you start the container pass the $ORG_NAME
and $ORG_PORT
to it. In this case docker will keep your entry point and overrides the default CMD
which is --help
in this case to the other options that you have passed and make sure to keep the command between quotes to be treated as single command
So in this case you will run the container as the following:
docker run -it --name my_container myimage:latest "$ORG_NAME $ORG_PORT"
Same scenario can be done with docker compose.
Upvotes: 0
Reputation: 158898
There's a couple of moving parts here.
For the things that need to be configurable, it's probably easiest to refer to them using process.env
in Node and not pass them as command-line arguments. In your second example, refer to process.env.ORG_NAME
, for example.
Some things don't need to be configurable. In your second example, you can pick a fixed TCP port for your service; even if you use the Express default port 3000, you can docker run -p 1401:3000
, docker run -p 1402:3000
, etc. to assign different ports to different containers running the same image. In your first example, you're trying to use an environment variable to specify the entire command; don't bother doing this and just use the standard Docker command line.
That would give you a routine Dockerfile like
FROM node:alpine
# Generally don't "git clone" in a Dockerfile.
WORKDIR /dlr_ui
COPY package.json package-lock.json ./
RUN npm install
COPY . ./
EXPOSE 3000
CMD ["node", "Core.js"]
And you don't need to worry about this particular problem at all. You'd run it like
docker run -d -p 1401:3000 -e ORG_NAME=ORG1 --name="Org1_UI" uinodetest
There are two syntaxes for the CMD, ENTRYPOINT, and RUN commands. The form that looks like a JSON array (but isn't actually) directly runs the command that's given, without invoking any kind of shell or interpreter or variable expansion. In your second example the script will be invoked with the literal strings $ORG_NAME
and ORG_PORT
as parameters. If you just write something that looks like a command, not using the JSONish syntax, it gets automatically wrapped in sh -c
.
I would expect, syntactically, that the first example does what you want (but see @BMitch's answer); but it would be simpler to just pass the command directly
docker run -d -p 1401:1401 --name="Org1_UI" uinodetest ./runOrg1.sh
Upvotes: 1
Reputation: 263627
Docker will pass the environment variable to your container, but you need a shell to parse the ${var}
syntax into that variable. You got close with:
CMD ["sh","./${ORG_SCRIPT}"]
I suspect the reason this didn't work is because the arg passed to sh
hasn't been expanded yet, and sh isn't processing that arg, it's just running it. Instead you need:
CMD ["sh","-c","./${ORG_SCRIPT}"]
That is almost exactly the same as the string/shell syntax, which I'd recommend instead:
CMD ./${ORG_SCRIPT}
Upvotes: 4