Docker CMD vs ENTRYPOINT: explaining the difference
Tags: docker, kubernetes, devops
Published: 2021-06-26 11:24:31

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](https://insights.stackoverflow.com/survey/2019#most-loved-dreaded-and-wanted), and  #1 most wanted platform, #2 most loved platform and #3 most popular platform in [the 2020 edition of the same survey](https://insights.stackoverflow.com/survey/2020#overview).

If you've bumped into this article, chances are that you have been bamboozled by the ~~[fruit doggo](https://i.pinimg.com/originals/3d/d6/ee/3dd6ee6d8b5c9979e0cbe1d7daafada9.jpg)~~ 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:

```docker
FROM alpine
CMD ["echo", "Hello, World!"]
```

Running it with:

```docker
docker container run my-container
```

Will yield the following result:

```docker
Hello, World!
```

> 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
docker container run my-container echo "Hello again!"
```

Will yield:

```docker
Hello again!
```

### ENTRYPOINT

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

```docker
FROM alpine
ENTRYPOINT ["echo", "Hello, World!"]
```

Will yield:

```docker
Hello, World!
```

### 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:

```docker
FROM alpine
ENTRYPOINT ["echo"]
CMD ["Hello, World!"]
```

Wil lead to us seeing:

```docker
Hello, World!
```

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