How to use docker arguments as arguments to a function inside it - docker

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/

Related

Docker pass arguments to docker without replacing default CMD

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.

Avoid override ENTRYPOINT base docker image

I have a base docker image pointing to daggerok/jboss-eap-7.1:7.1.0-alpine and it execute a ENTRYPOINT that i don't want to override. But i also need execute another command after base image execute theirs, so my Dockerfile looks like it:
FROM daggerok/jboss-eap-7.1:7.1.0-alpine
#SOME CODE HERE
ENTRYPOINT ["mybash.sh"]
I think this code override ENTRYPOINT in base image, and i need avoid it. My script need to be executed after all commands in base image.
Any tips to solve it ?
There are some problems to achieve what you want:
You cannot find out the ENTRYPOINT of the base image at runtime within a .sh-script, so you cannot execute it, without copying it explicitly into your mybash.sh
The ENTRYPOINT of the base image you mention is /bin/bash ${JBOSS_HOME}/bin/standalone.sh which launches the main process with id 1 of your docker container. You should not alter that and start this in background for example. Read further here.
I would advise to rewrite mybash.sh:
First execute whatever you would like before starting jboss. Then, finish your script with a last line starting jboss:
exec "/bin/bash ${JBOSS_HOME}/bin/standalone.sh" (adapted from here)

Difference between Docker Build and Docker Run

If I want to run a python script in my container what is the point in having the RUN command, if I can pass in an argument at build along with running the script?
Each time I run the container I want x.py to be run on an ENV variable passed in during the build stage.
If I were to use Swarm, and the only goal was to run the x.py script, swarm would only be building nodes, rather than building and eventually running, since the CMD and ENTRYPOINT instructions only happen at run time.
Am I missing something?
The docker build command creates an immutable image. The docker run command creates a container that uses the image as a base filesystem, and other metadata from the image is used as defaults to run that image.
Each RUN line in a Dockerfile is used to add a layer to the image filesystem in docker. Docker actually performs that task in a temporary container, hence the selection of the confusing "run" term. The only thing preserved from that RUN command are the filesystem changes, running processes, changes to environment variables, shell settings like the current working directory, are all lost when the temporary container is cleaned up at the completion of the RUN command.
The ENTRYPOINT and CMD value are used to specify the default command to run when the container is started. When both are defined, the result is the value of the entrypoint is run with the value of the cmd appended as a command line argument. The value of CMD is easily overridden at the end of the docker run command line, so by using both you can get easy to reconfigure containers that run the same command with different user input parameters.
If the command you are trying to run needs to be performed every time the container starts, rather than being stored in the immutable image, then you need to perform that command in your ENTRYPOINT or CMD. This will add to the container startup time, so if the result of that command can be stored as a filesystem change and cached for all future containers being run, you want to make that setting in a RUN line.

Is CMD in parent docker overriden by CMD/ENTRYPOINT in child docker image?

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.

Feed variable arguments to Docker ENTRYPOINT

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

Resources