Avoid override ENTRYPOINT base docker image - docker

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)

Related

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.

How can I change a docker image start

I have a SOLR image starting with a default configuration when I start my container.
I want to change the way SOLR starts in my container by referencing a different configuration file. Of course, I still want to use the original image I had from the beginning.
What is the best practice to do so?
If I use a docker file referencing my original image it will start it with the default value as no script has been modified.
I also thought about committing my new configuration file on my image, that works but that still does not change the starting script.
Can someone guide me on the best practice to do that?
Thanks in advance for your help.
Startup of a container is always controlled by ENTRYPOINT & CMD. In this case if you want to override it, you can create your own script & define it in the CMD & ENTRYPOINT defines a null environment to execute CMD but moreover, it overwrites your previous ENTRYPOINT in Dockerfile(You can provide a different ENTRYPOINT script as well). You can do it as below in Dockerfile -
FROM solr:latest
...................
...................
COPY your-data /container-data
ENTRYPOINT ["/usr/bin/env"]
CMD /run.sh
You can copy your data inside container using COPY & define operations to be performed in run.sh, run.sh is your own script which you want to get executed on container startup.

Docker build state

I have an existential question about docker. Given this dockerfile:
FROM someImage
MAINTAINER abc
ENV something=somehow
RUN sh calculatePi.sh
ENV somethingElse=somehow2
"Calculate Pi" is a "continuous" program that never ends and needs to be ran on the background. It calculates all the digits of PI (3.1415.....) and save it to a txt file.
My question:
Is this dockerfile even plausible?
If Yes, When I run a container based on this image, what is the saved state? In other words, if I open the txt file, what would I see?
When Docker builds an image, each instruction in the Dockerfile gets executed in an interim container, run from the preceding image layer. So if your calculatePi.sh ran endlessly then your image would never build - it would stick at the RUN instruction waiting for it to complete.
In practice, it's more likely that you'll max out disk or CPU resource and take down the machine if you tried to build it. Either way, you wouldn't get a completed image that you could run.
No, that Dockerfile won't work. RUN instructions need to complete before Docker can create an image from them. Perhaps you want to make that a CMD instruction instead?
May be you can write your docker file like this:
FROM someImage
MAINTAINER abc
ENV something=somehow
ENV somethingElse=somehow2
ENTRYPOINT ["/bin/bash"]
CMD ["calculatePi.sh"]
Then when you run this image
docker run -d thisImage
The script calculatePi.sh will run in your container as an App.

Run commands on create a new Docker container

Is it possible to add instructions like RUN in Dockerfile that, instead of run on docker build command, execute when a new container is created with docker run? I think this can be useful to initialize a volume attached to host file system.
Take a look at the ENTRYPOINT command. This specifies a command to run when the container starts, regardless of what someone provides as a command on the docker run command line. In fact, it is the job of the ENTRYPOINT script to interpret any command passed to docker run.
I think you are looking for the CMD
https://docs.docker.com/reference/builder/#cmd
The main purpose of a CMD is to provide defaults for an executing
container. These defaults can include an executable, or they can omit
the executable, in which case you must specify an ENTRYPOINT
instruction as well.
Note: don't confuse RUN with CMD. RUN actually runs a command and
commits the result; CMD does not execute anything at build time, but
specifies the intended command for the image.
You should also look into using Data Containers see this excellent Blog post.
Persistent volumes with Docker - Data-only container pattern
http://container42.com/2013/12/16/persistent-volumes-with-docker-container-as-volume-pattern/

Resources