DEV Community

Cover image for Docker CMD vs ENTRYPOINT
Gayan Hewa
Gayan Hewa

Posted on

Docker CMD vs ENTRYPOINT

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)

Collapse
 
jdcskillet profile image
Joe Cavanaugh

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...

Collapse
 
jdcskillet profile image
Joe Cavanaugh • Edited

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).

#######################################################################################################################
#
# Stage: Runner
# Purpose: Runs any NPM scripts using Yarn. Defaults to running unit tests.
#
#######################################################################################################################
FROM installer AS runner

CMD [ "yarn", "test", "--coverage" ]

#######################################################################################################################
#
# Stage: E2E Runner
# Purpose: Runs end-to-end tests. This stage will use BrowserStack if the proper environment variables are provided.
#
#######################################################################################################################
FROM builder AS e2e-runner

ENTRYPOINT [ "yarn", "test:e2e" ]
CMD [ "--env", "chromeHeadless", "--timeout", "60000", "--tags", "@criticalPath" ]
Collapse
 
gayanhewa profile image
Gayan Hewa

Neat πŸ‘

Collapse
 
alvinabad profile image
Alvin Abad • Edited

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.

sh -c CMD
Enter fullscreen mode Exit fullscreen mode

If you define an ENTRYPOINT, docker will run your container like this:

ENTRYPOINT CMD
Enter fullscreen mode Exit fullscreen mode
Collapse
 
napicella profile image
Nicola Apicella

Short and sweet :)