docker - What is the difference between CMD and ENTRYPOINT in a Dockerfile?

ID : 367

viewed : 187

Tags : dockerdocker





Top 5 Answer for docker - What is the difference between CMD and ENTRYPOINT in a Dockerfile?

vote vote

98

Docker has a default entrypoint which is /bin/sh -c but does not have a default command.

When you run docker like this: docker run -i -t ubuntu bash the entrypoint is the default /bin/sh -c, the image is ubuntu and the command is bash.

The command is run via the entrypoint. i.e., the actual thing that gets executed is /bin/sh -c bash. This allowed Docker to implement RUN quickly by relying on the shell's parser.

Later on, people asked to be able to customize this, so ENTRYPOINT and --entrypoint were introduced.

Everything after ubuntu in the example above is the command and is passed to the entrypoint. When using the CMD instruction, it is exactly as if you were doing docker run -i -t ubuntu <cmd>. <cmd> will be the parameter of the entrypoint.

You will also get the same result if you instead type this command docker run -i -t ubuntu. You will still start a bash shell in the container because of the ubuntu Dockerfile specified a default CMD: CMD ["bash"]

As everything is passed to the entrypoint, you can have a very nice behavior from your images. @Jiri example is good, it shows how to use an image as a "binary". When using ["/bin/cat"] as entrypoint and then doing docker run img /etc/passwd, you get it, /etc/passwd is the command and is passed to the entrypoint so the end result execution is simply /bin/cat /etc/passwd.

Another example would be to have any cli as entrypoint. For instance, if you have a redis image, instead of running docker run redisimg redis -H something -u toto get key, you can simply have ENTRYPOINT ["redis", "-H", "something", "-u", "toto"] and then run like this for the same result: docker run redisimg get key.

vote vote

81

The ENTRYPOINT specifies a command that will always be executed when the container starts.

The CMD specifies arguments that will be fed to the ENTRYPOINT.

If you want to make an image dedicated to a specific command you will use ENTRYPOINT ["/path/dedicated_command"]

Otherwise, if you want to make an image for general purpose, you can leave ENTRYPOINT unspecified and use CMD ["/path/dedicated_command"] as you will be able to override the setting by supplying arguments to docker run.

For example, if your Dockerfile is:

FROM debian:wheezy ENTRYPOINT ["/bin/ping"] CMD ["localhost"] 

Running the image without any argument will ping the localhost:

$ docker run -it test PING localhost (127.0.0.1): 48 data bytes 56 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.096 ms 56 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.088 ms 56 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.088 ms ^C--- localhost ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.088/0.091/0.096/0.000 ms 

Now, running the image with an argument will ping the argument:

$ docker run -it test google.com PING google.com (173.194.45.70): 48 data bytes 56 bytes from 173.194.45.70: icmp_seq=0 ttl=55 time=32.583 ms 56 bytes from 173.194.45.70: icmp_seq=2 ttl=55 time=30.327 ms 56 bytes from 173.194.45.70: icmp_seq=4 ttl=55 time=46.379 ms ^C--- google.com ping statistics --- 5 packets transmitted, 3 packets received, 40% packet loss round-trip min/avg/max/stddev = 30.327/36.430/46.379/7.095 ms 

For comparison, if your Dockerfile is:

FROM debian:wheezy CMD ["/bin/ping", "localhost"] 

Running the image without any argument will ping the localhost:

$ docker run -it test PING localhost (127.0.0.1): 48 data bytes 56 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.076 ms 56 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.087 ms 56 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.090 ms ^C--- localhost ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.076/0.084/0.090/0.000 ms 

But running the image with an argument will run the argument:

docker run -it test bash root@e8bb7249b843:/# 

See this article from Brian DeHamer for even more details: https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd/

vote vote

78

According to docker docs,

Both CMD and ENTRYPOINT instructions define what command gets executed when running a container. There are few rules that describe their co-operation.

  1. Dockerfile should specify at least one of CMD or ENTRYPOINT commands.
  2. ENTRYPOINT should be defined when using the container as an executable.
  3. CMD should be used as a way of defining default arguments for an ENTRYPOINT command or for executing an ad-hoc command in a container.
  4. CMD will be overridden when running the container with alternative arguments.

The tables below shows what command is executed for different ENTRYPOINT / CMD combinations:

-- No ENTRYPOINT

╔════════════════════════════╦═════════════════════════════╗ ║ No CMD                     ║ error, not allowed          ║ ╟────────────────────────────╫─────────────────────────────╢ ║ CMD ["exec_cmd", "p1_cmd"] ║ exec_cmd p1_cmd             ║ ╟────────────────────────────╫─────────────────────────────╢ ║ CMD ["p1_cmd", "p2_cmd"]   ║ p1_cmd p2_cmd               ║ ╟────────────────────────────╫─────────────────────────────╢ ║ CMD exec_cmd p1_cmd        ║ /bin/sh -c exec_cmd p1_cmd  ║ ╚════════════════════════════╩═════════════════════════════╝ 

-- ENTRYPOINT exec_entry p1_entry

╔════════════════════════════╦══════════════════════════════════╗ ║ No CMD                     ║ /bin/sh -c exec_entry p1_entry   ║ ╟────────────────────────────╫──────────────────────────────────╢ ║ CMD ["exec_cmd", "p1_cmd"] ║ /bin/sh -c exec_entry p1_entry   ║ ╟────────────────────────────╫──────────────────────────────────╢ ║ CMD ["p1_cmd", "p2_cmd"]   ║ /bin/sh -c exec_entry p1_entry   ║ ╟────────────────────────────╫──────────────────────────────────╢ ║ CMD exec_cmd p1_cmd        ║ /bin/sh -c exec_entry p1_entry   ║ ╚════════════════════════════╩══════════════════════════════════╝ 

-- ENTRYPOINT ["exec_entry", "p1_entry"]

╔════════════════════════════╦═════════════════════════════════════════════════╗ ║ No CMD                     ║ exec_entry p1_entry                             ║ ╟────────────────────────────╫─────────────────────────────────────────────────╢ ║ CMD ["exec_cmd", "p1_cmd"] ║ exec_entry p1_entry exec_cmd p1_cmd             ║ ╟────────────────────────────╫─────────────────────────────────────────────────╢ ║ CMD ["p1_cmd", "p2_cmd"]   ║ exec_entry p1_entry p1_cmd p2_cmd               ║ ╟────────────────────────────╫─────────────────────────────────────────────────╢ ║ CMD exec_cmd p1_cmd        ║ exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd  ║ ╚════════════════════════════╩═════════════════════════════════════════════════╝ 
vote vote

69

Yes, that is a good question. I don't understand it fully yet, but:

I understand that ENTRYPOINT is the binary that is being executed. You can overide entrypoint by --entrypoint="".

docker run -t -i --entrypoint="/bin/bash" ubuntu 

CMD is the default argument to container. Without entrypoint, default argument is command that is executed. With entrypoint, cmd is passed to entrypoint as argument. You can emulate a command with entrypoint.

# no entrypoint docker run ubuntu /bin/cat /etc/passwd  # with entry point, emulating cat command docker run --entrypoint="/bin/cat" ubuntu /etc/passwd 

So, main advantage is that with entrypoint you can pass arguments (cmd) to your container. To accomplish this, you need to use both:

# Dockerfile FROM ubuntu ENTRYPOINT ["/bin/cat"] 

and

docker build -t=cat . 

then you can use:

docker run cat /etc/passwd #              ^^^^^^^^^^^ #                   CMD #          ^^^       #          image (tag)- using the default ENTRYPOINT 
vote vote

54

In a nutshell:

  • CMD sets default command and/or parameters, which can be overwritten from command line when docker container runs.
  • ENTRYPOINT command and parameters will not be overwritten from command line. Instead, all command line arguments will be added after ENTRYPOINT parameters.

If you need more details or would like to see difference on example, there is a blog post that comprehensively compare CMD and ENTRYPOINT with lots of examples - http://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/

Top 3 video Explaining docker - What is the difference between CMD and ENTRYPOINT in a Dockerfile?







Related QUESTION?