Say I have this line in a Dockerfile:
ENTRYPOINT ["/usr/src/app/node_modules/suman/cli.js","a","b","c"]
what is the best way to programmatically populate a b and c? I am not sure how I can avoid hardcoding ENTRYPOINT.
There are some ways of getting around this. I could pass all my arguments in one variable, and hardcode that one variable, something like so:
ENTRYPOINT ["/usr/src/app/node_modules/suman/cli.js","--all-args=${x}"]
but I frankly don't know how to achieve either properly and I'd rather solve it using the first a, b, c pattern if possible. Anyone know of the way to do this?
If you want to change what the parameters are, why not pass them on the docker run line?
with ENTRYPOINT ["/usr/src/app/node_modules/suman/cli.js"]:
docker run -ti yourimage a b c
Arguments after your image name will be passed just like traditional arguments. Here, cli.js will receive them as argv arguments.
Use double quotes on the docker run command " if you want single arguments containing spaces to be properly handled.
I can also suggest you to use a proper entrypoint for Docker, so that a few more things like CTR+C and STOP signals as well as programmatic features are handled better.
In order to achieve this, it seems best to simply omit the ENTRYPOINT line in the Dockerfile altogether and then pass in the --entrypoint value using docker run, like so:
docker run --entrypoint="/usr/src/app/node_modules/suman/cli.js" --name ${container_name} ${image_tag} ${argz}
You can read about overriding entrypoint here:
https://medium.com/#oprearocks/how-to-properly-override-the-entrypoint-using-docker-run-2e081e5feb9d
Related
If I have docker run ... -e VAR=x ... -e VAR=y ..., what is the value of VAR in the container? From a quick test it looks like the last one is used, but is this guaranteed anywhere in the documentation?
No, this is not guaranteed as far as I can tell. Here are the relevant locations in the documentation:
The docker run reference
The docker run command line reference
Also the docker daemon API does not specify what happens on duplicate entries in the Env array.
There is also the documentation on Environment variables precedence for docker-compose. But this also does not mention duplicate keys in one of the layers.
You are probably best advised to not rely on the fact that this is implemented as it is.
I am writing a dockerfile that runs a pp that wil use the same argument most of the time.
ENTRYPOINY [ "mayapp" ]
CMD [ "defaultarg" ]
But every now and the it needs to take another argument, since the users will be mostly windows I want to do this without many scripts or extra arguments
docker run my/app somearg
Issue is they need to use a bind volume. However when I add a -v switch it will take that to override the CMD.
docker run my/app -v datadir:/app/datadir
This will replace 'defaultarg' with '-v'
Is there a way to stop this from happening without moving the CMD arg to a env/ARG?
I have used the build args switch because I couldn't find any info. However resolving this without build-args would be nicer since it less switches on running the container.
Parameters on docker run come in 2 flavours. Parameters for docker are placed before the image name and parameters for the container are placed after the image name. As you've discovered, parameters for the container replace any CMD statement in the image.
The -v parameter is for docker, so it should go before the image name, like this
docker run -v datadir:/app/datadir my/app
That will leave your CMD intact, so it'll work as before.
I am trying to get my hands dirty on docker. I know that CMD or ENTRYPOINT is used to specify the start/runnable command for docker image and CMD is overridden by ENTRYPOINT. But I don't know, how does it works, when parent docker image, also has CMD OR ENTRYPOINT or BOTH ?
Does child image inherit those values from parent docker image ? If so, then does ENTRYPOINT in parent image override CMD in child image ?
I know that such question is already discussed at https://github.com/docker/compose/issues/3140. But, the discussion is quite old(before 2-3 years) and it doesn't answer my question clearly.
Thanks in advance.
If you define an ENTRYPOINT in a child image, it will null out the value of CMD as identified in this issue. The goal is to avoid a confusing situation where an entrypoint is passed as args a command you no longer want to run.
Other than this specific situation, the value of ENTRYPOINT and CMD are inherited and can be individually overridden by a child image or even a later step of the same Dockerfile. Only one value for each of these will ever exist in an image with the last defined value having precedence.
ENTRYPOINT doesn't override CMD, they just represent to parts of resulting command and exist to make life easier. Whenever container is started, the command for process 1 is determined as ENTRYPOINT + CMD, so usually ENTRYPOINT is just path to the binary and CMD is a list of arguments for that binary. CMD can also be easily overriden from command line.
So, again, it's just a thing to make life easier and make containers behave just like regular binaries - if you have man container, you can set entrypoint to /usr/bin/man and cmd to man. So if you just start container, docker will execute /usr/bin/man man, but if you run something like docker run man docker, the resulting container command will be /usr/bin/man docker - the entrypoint stays the same, cmd changes, and resulting command to start container is just a simple merging of those.
ENTRYPOINT and CMD are both inherited from parent layers (images) unless overriden, so if you inherit from image X and redefine CMD, you will still have the very same ENTRYPOINT and vice versa. However, as #BMitch mentioned below, changing ENTRYPOINT in child image will effectively reset CMD.
I am trying to get the arguments from the docker image and then I want to use that argument as an argument to the function inside the docker.
For example:
CMD ["python", "xyz.py","--input=/input_data","--output=/output_data"]
I want to enter the locations of input and output commandline
or
CMD ["python", "add.py","--input1=4","--input2=5"]
I want to enter 4 and 5 from command line to get the sum as a result, in this way I can generalize my docker very well.
How can i do this?
As far as I can understand, what you want is to create, in the second case, a container that adds two elements.
If I am right, and what you want to execute at the moment is something like:
docker run add:latest 4 6
What you have to do is a script with the python add.py and include it as ENTRYPOINT, not in the CMD. Then you could call: docker run add: latest 4 5 and get the sum of both.
The CMD can be overwritten in docker run. Look at this post:
http://www.johnzaccone.io/entrypoint-vs-cmd-back-to-basics/
I was looking around and I saw some simple examples of HelloWorld running on a docker container like this one:
http://dotnet.dzone.com/articles/docker-%E2%80%98hello-world-mono
at the end of the Dockerfile, the author calls:
CMD ["mono", "/src/hello.exe"]
What I want to do is have a reusable image as we build our Console App. Put that on a docker image using a Dockerfile. That part makes sense to me. But then I want to be able to pass the ConsoleApp parameters. Is that possible?
for example,
sudo docker run crystaltwix/helloworld -n "crystal twix"
where -n was a parameter I defined in my helloworld app.
You can use ENTRYPOINT foo rather than CMD foo to achieve this. All arguments after the docker run are passed to foo.
#seanmcl's answer is the simplest... if you have to pass secret values like application keys you may have to worry about exposing them is process lists.... So, you could use environment vars that you app looks for during startup:
SECRET_KEY="crystal twix"
docker run -e APP_KEY=$SECRET_KEY crystaltwix/helloworld