TL;DR
CMD
allows you to define the default command with params when the image gets executed in a container.
ENTRYPOINT
allows you to specify a command or script that needs to be executed.
Both can be used in conjunction to get them to specify the Entrypoint and default arguments.
This is a quick summary of the difference between CMD and ENTRYPOINT and to know when to use what.
In essence, when you execute:
docker run ubuntu
The docker container would run and exit immediately. This due to the fact that containers are expected to die out soon as it's done with what it's supposed to do. For instance, running the above command will execute bash
and immediately exit.
But, if you do the following:
docker run -it ubuntu top
This would result in the container running the top
command on the container and it will wait for us to exit the program so that it would exit.
So, in general, the container's lifespan is only until the task it's assigned to run completes.
CMD
The CMD command in docker, basically allows us to execute a command. Defining this at the end of the Dockerfile allows us to create an image that will execute that given command whenever the image is invoked.
FROM alpine
CMD ["sleep", "10"]
This script would literally halt the container for 10 seconds before it exits.
We still have the ability to override the CMD command by specifying a command on the URL.
docker run name-of-the-image-built sleep 1
ENTRYPOINT
Entrypoint basically executes a command / script anything that you would specify and passes trough whatever that you specify in the docker run command.
FROM alpine
ENTRYPOINT ["sleep"]
When you build and run this Dockerfile, it will basically fail.
docker run alpine-with-entry-point
Because the sleep command expects 1 argument. So to get this to work, you would run:
docker run alpine-with-entry-point 10
Doing the above is essentially equal to saying sleep 10
when the image gets run.
The downside with an Entrypoint is, that if your command needs an argument like in the example above, you need to specify it always. Not having would result in the container crashing with an error. To overcome this we can do the following:
FROM alpine
ENTRYPOINT ["sleep"]
CMD ["10"]
This would essentially make sure that 10 gets passed into the sleep command as a default argument if nothing is passed. Avoiding any crashes due to missing args.
Most of the content I have written about here are my notes from following the docker course I came across on youtube
Top comments (5)
Well done, I like this overview of the two commands. It breaks it down in an easy to understand chunk without adding a ton of unnecessary detail.
I would add that if someone wants the additional technical information to refer to:
docs.docker.com/engine/reference/b...
docs.docker.com/engine/reference/b...
An anecdote of how I have used Entrypoint vs CMD. When running the unit tests in a Jenkins pipeline I initiate the runner stage. When I run the e2e tests I want to make sure the system is executing the e2e yarn with sane defaults, so we execute an ENTRYPOINT where we can easily override the params (it also makes the command shorter in the Jenkinsfile).
Neat 👍
Another way to understand the difference is that the ENTRYPOINT is the executable program while the CMD is the argument of the ENTRYPOINT. If you don't specify the ENTRYPOINT and only the CMD, docker will use the default ENTRYPOINT
sh -c
, if it is available in the image.If you only specify the CMD, it will appear as if you are executing the CMD but in reality the container will run like that below which is equivalent to running the CMD.
If you define an ENTRYPOINT, docker will run your container like this:
Short and sweet :)