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

We can build Docker images by specifying instructions inside a Dockerfile. Dockerfile allows us to specify step-by-step instructions which define the rules for making a container environment. The Docker containers are created for specific tasks and processes to be run inside them. There are three important instructions that are used inside a Dockerfile which lets us define which processes need to be run inside the containers and in what sequence and order.

These 3 instructions are -

  • RUN
  • CMD

The RUN instruction is quite simple. We can define simple subcommands along with the RUN instruction that we want to execute inside the container. For example, if we want to install a pip package, we can simply use the “RUN pip install package_name” instruction inside the Dockerfile.

However, the other two instructions - CMD and ENTRYPOINT can be quite confusing, especially for beginners. In this article, we are going to discuss the use-cases and the distinctions between these two commands along with some useful examples. But before we get into them, we need to understand the shell and exec forms of writing instructions in a Dockerfile

Shell form

When we use shell form to specify instructions, normal shell processing takes place in the background. The daemon calls the command shell in the background while executing the shell form of commands. The format to specify the commands in shell form is -

$ <instruction> <command>

Executable Form

When we write commands in executable form and execute those commands, then the normal shell processing does not happen in the background. Instead, the executable gets directly called. The format to specify commands in executable form is -

$ <instruction> ["executable", "parameter", "parameter", . . . .]

The shell form of commands is generally used for RUN instructions and the executable forms are generally used for CMD and ENTRYPOINT instructions.

CMD Instruction

You can set default commands with parameters using the CMD instruction. If you run a Docker container without specifying any additional CLI commands, the CMD instruction will be executed. You can include an executable as the default command. However, if you choose to omit it, you will have to specify an ENTRYPOINT instruction along with the CMD instruction

If you have specified an argument along with the Docker run command, the default one specified using the CMD instruction will be ignored. Also, if you have specified multiple CMD instructions inside a single dockerfile, the one specified at the last will only be executed.

The CMD instruction has three forms -

  • CMD ["only_executable","parameter_1","parameter_1"] (executable form)
  • CMD ["parameter_1","parameter_2"] (used to provide default parameters to the ENTRYPOINT instruction)
  • CMD command param1 param2 (It is the shell form)

Example -

$ CMD echo "Command in Shell Form"
$ CMD ["/bin/bash", "-c", "echo Command in Exec Form"]

ENTRYPOINT Instruction

The ENTRYPOINT instruction looks almost similar to the CMD instruction. However, the main highlighting difference between them is that it will not ignore any of the parameters that you have specified in the Docker run command (CLI parameters).

When we have specified the ENTRYPOINT instruction in the executable form, it allows us to set or define some additional arguments/parameters using the CMD instruction in Dockerfile. If we have used it in the shell form, it will ignore any of the CMD parameters or even any CLI arguments.

The forms of the ENTRYPOINT Instruction are -

  • ENTRYPOINT ["only_executable", "parameter_1", "parameter_2"] (executable form)
  • ENTRYPOINT command parameter_1 parameter_2 (Shell form)

Example -

$ ENTRYPOINT echo "Welcome to TutorialsPoint"
$ ENTRYPOINT ["/bin/bash", "-c", "echo Welcome to TutorialsPoint"]

Final Thoughts!

To sum up, if you want to specify default commands with arguments that need to be run when you fire up a Docker container, you can use the CMD instruction. In case you specify an argument along with the Docker run command, the arguments specified using the CMD instruction will be ignored. This means that the CLI arguments using the Docker run command will override the arguments specified using the CMD instruction.

On the other hand, there are two cases with the ENTRYPOINT instruction. If you use the ENTRYPOINT instruction in the shell form and you provide additional arguments using CLI parameters or even through the CMD commands, the ENTRYPOINT instruction overrides all of these. However, if you use ENTRYPOINT instruction in executable form, you can set additional parameters using the CMD instruction.

Depending on your requirements and use-cases, you can adopt any one of these commands.