DEV Community

loading...

Docker CMD vs ENTRYPOINT: explaining the difference

Andrea Cappuccio
Originally published at stackrant.com ・3 min read

We IT people LOVE tinkering with new tech stuff, and Docker is no exception. As a matter of fact, Docker was ranked as the #1 most wanted platform, #2 most loved platform, and #3 most broadly used platform in the 2019 Stack Overflow Developer Survey, and #1 most wanted platform, #2 most loved platform and #3 most popular platform in the 2020 edition of the same survey.

If you've bumped into this article, chances are that you have been bamboozled by the fruit doggo difference between the CMD and ENTRYPOINT instructions defined in a Dockerfile, used to describe how a Docker container should be run.

But what's a Docker container?

Containers are lightweight, standalone, executable packages of software designed for running specific tasks, no matter if short-lived or long-running. Therefore, a container's lifecycle depends on the ongoing process inside of it.

Once the process stops, the container stops as well.

Ok, but what role is our Dockerfile playing here?

Containers are dependent on images and use them to construct a run-time environment in order to run an application. A Dockerfile is a script which role is to define the process which leads to the creation of a final image, and how to run a container bound to said image.

The process of creating a Docker image usually begins with a FROM command, defining a base image to build our image upon. We usually follow up with a bunch of RUN instructions, used to run commands which modify the underlying filesystem.

Each RUN instruction creates a new image layer that contains a modification to the filesystem.

Fine. Now what about the CMD vs ENTRYPOINT stuff?

CMD and ENTRYPOINT are two different types of instructions used to define how a Docker container should be run.
Let's dive into the details of each one:

CMD

A CMD instruction defines the default command used to run a Docker container from an image.

Given a simple image like the following:

FROM alpine
CMD ["echo", "Hello, World!"]
Enter fullscreen mode Exit fullscreen mode

Running it with:

docker container run my-container
Enter fullscreen mode Exit fullscreen mode

Will yield the following result:

Hello, World!
Enter fullscreen mode Exit fullscreen mode

A Dockerfile can contain multiple CMD instructions, but every single one of them, except for the last one, will be ignored.

A CMD instruction can be overridden by the arguments passed to docker container run, like:

docker container run my-container echo "Hello again!"
Enter fullscreen mode Exit fullscreen mode

Will yield:

Hello again!
Enter fullscreen mode Exit fullscreen mode

ENTRYPOINT

ENTRYPOINT instructions define, just like their CMD siblings, the default command used to start a container.

FROM alpine
ENTRYPOINT ["echo", "Hello, World!"]
Enter fullscreen mode Exit fullscreen mode

Will yield:

Hello, World!
Enter fullscreen mode Exit fullscreen mode

Cool, so... what's the difference at this point?

Well, the main difference is that, if both a CMD and ENTRYPOINT instructions are defined inside a Dockerfile, the CMD instruction will be concatenated to the ENTRYPOINT one:

FROM alpine
ENTRYPOINT ["echo"]
CMD ["Hello, World!"]
Enter fullscreen mode Exit fullscreen mode

Wil lead to us seeing:

Hello, World!
Enter fullscreen mode Exit fullscreen mode

Also, while CMD instructions are, by design, made do be easily overridden by passing arguments to docker container run commands, ENTRYPOINT have purposely been made harder to override manually, by forcing user to use a --entrypoint flag.

This leads us to a pattern

This design leads us to a consistent pattern. And we like patterns, patterns are good for our mental health:

We can use ENTRYPOINT to define a base command which always gets executed, and CMD to define default arguments for this command, easily overridable by passing custom args to docker container run.

Discussion (3)

Collapse
supportic profile image
Supportic

Entrypoint is the main program to execute. E.g. /bin/bash
Comand is used to pass parameters.
The good thing about comand is, that you can provide a default fallback for the compose file and OVERWRITE it if needed when using the docker CLI.

Collapse
csgeek profile image
csgeek • Edited

I've always like kubernetes choice to call it command and args. Always made more sense to me than entrypoint and cmd for arguments.

Collapse
clalarco profile image
Claudio Alarcon-Reyes

ENTRYPOINT is the first process 1 of the instance (PID 0). Some systems currently use TINI to manage zombie processes and other stuff.