I'm new to Docker and I'm having a hard time to setup the docker container as I want. I have a nodejs app can take two parameters when start. For example, I can use
node server.js 0 dev
or
node server.js 1 prod
to switch between production mode and dev mode and determine if it should turn the cluster on. Now I want to create docker image with arguments to do the similar thing, the only thing I can do so far is to adjust the Dockerfile to have a line
CMD [ "node", "server.js", "0", "dev"]
and
docker build -t me/app .
to build the docker.
Then docker run -p 9000:9000 -d me/app
to run the docker.
But If I want to switch to prod mode, I need to change the Dockerfile CMD to be
CMD [ "node", "server.js", "1", "prod"]
,
and I need to kill the old one listening on port 9000 and rebuild the image. I wish I can have something like
docker run -p 9000:9000 environment=dev cluster=0 -d me/app
to create an image and run the nodejs command with "environment" and "cluster" arguments, so I don't need to change the Dockerfile and rebuild the docker any more. How can I accomplish this?
The typical way to do this in Docker containers is to pass in environment variables:
Make sure your Dockerfile declares an environment variable with
ENV
:The
ENV <key> <value>
form can be replaced inline.Then you can pass an environment variable with docker run
Or you can set them through your compose file:
Your Dockerfile
CMD
can use that environment variable, but, as mentioned in issue 5509, you need to do so in ash -c
form:Same idea with Builder RUN (applies to
CMD
as well):Another option is to use
ENTRYPOINT
to specify thatnode
is the executable to run andCMD
to provide the arguments. The docs have an example in Exec form ENTRYPOINT example.Using this approach, your Dockerfile will look something like
Running it in dev would use the same command
and running it in prod you would pass the parameters to the run command
You may want to omit
CMD
entirely and always pass in0 dev
or1 prod
as arguments to the run command. That way you don't accidentally start a prod container in dev or a dev container in prod.