Difference of CMD and ENTRYPOINT Commands in Dockerfile

Ask questions Research chat →

https://sefidian.com/2021/10/29/difference-of-cmd-and-entrypoint-commands-in-dockerfile/ · scraped

deploy

Scraped Content

— 1915 words · 2026-06-11 17:22:20 UTC ·

Excerpt

Introduction Containers are designed for running specific tasks and processes, not for hosting operating systems. You create a container to serve a single unit task. Once it completes the given task, it stops. Therefore, the container life-cycle depends on the ongoing process inside of it. Once the process stops, the container stops as well. A Dockerfile defines this process. It is a script made up of instructions on how to build a Docker image. In this script, there are two types of instructions that can define the process running in the container: - ENTRYPOINT - CMD In this article, we explain the differences between Docker ENTRYPOINT and CMD and when to use which Docker instruction. ## Docker Entrypoint vs CMD: Solving the Dilemma In short, CMD defines default commands and/or parameters for a container. CMD is an instruction that is best to use if you need a default command which users can easily override. If a Dockerfile has multiple CMDs, it only applies the instructions from
Introduction Containers are designed for running specific tasks and processes, not for hosting operating systems. You create a container to serve a single unit task. Once it completes the given task, it stops. Therefore, the container life-cycle depends on the ongoing process inside of it. Once the process stops, the container stops as well. A Dockerfile defines this process. It is a script made up of instructions on how to build a Docker image. In this script, there are two types of instructions that can define the process running in the container: - ENTRYPOINT - CMD In this article, we explain the differences between Docker ENTRYPOINT and CMD and when to use which Docker instruction. ## Docker Entrypoint vs CMD: Solving the Dilemma In short, CMD defines default commands and/or parameters for a container. CMD is an instruction that is best to use if you need a default command which users can easily override. If a Dockerfile has multiple CMDs, it only applies the instructions from the last one. On the other hand, ENTRYPOINT is preferred when you want to define a container with a specific executable. You cannot override an ENTRYPOINT when starting a container unless you add the --entrypoint flag. Combine ENTRYPOINT with CMD if you need a container with a specified executable and a default parameter that can be modified easily. For example, when containerizing an application use ENTRYPOINT and CMD to set environment-specific variables. ## Shell and Exec Form Before we begin, it is important to discuss the forms of instructions. Docker ENTRYPOINT and CMD can have two forms: - Shell form - Exec form The syntax for any command in shell form is: The syntax for instructions in exec form is: You can write Docker CMD/ENTRYPOINT instructions in both forms: - CMD echo "Hello World" (shell form) - CMD ["echo", "Hello World"] (exec form) - ENTRYPOINT echo "Hello World" (shell form) - ENTRYPOINT ["echo", "Hello World"] (exec form) However, try to keep all your instructions in exec form to prevent potential performance issues. ## Docker CMD Docker CMD defines the default executable of a Docker image. You can run this image as the base of a container without adding command-line arguments. In that case, the container runs the process specified by the CMD command. The CMD instruction is only utilized if there is no argument added to the run command when starting a container. Therefore, if you add an argument to the command, you override the CMD. To show you how CMD works, we will create a sample container with CMD instruction. ## Docker Entrypoint ENTRYPOINT is the other instruction used to configure how the container will run. Just like with CMD, you need to specify a command and parameters. What is the difference between CMD and ENTRYPOINT? You cannot override the ENTRYPOINT instruction by adding command-line parameters to the docker run command. By opting for this instruction, you imply that the container is specifically built for such use. Read on to see how we apply ENTRYPOINT in container creation. ## Docker Entrypoint with CMD As you have seen so far, ENTRYPOINT and CMD are similar, but not the same. What’s more, these two instructions are not mutually exclusive. That’s right, it is possible to have both in your Dockerfile. There are many situations in which combining CMD and ENTRYPOINT would be the best solution for your Docker container. In such cases, the executable is defined with ENTRYPOINT, while CMD specifies the default parameter. If you are using both instructions, make sure to keep them in exec form. Read on to see how ENTRYPOINT and CMD collaborate in our example. ## CMD vs ENTRYPOINT: Fundamental differences CMD and ENTRYPOINT instructions have fundamental differences in how they function, making each one suitable for different applications, environments, and scenarios. They both specify programs that execute when the container starts running, but: - CMD commands are ignored by Daemon when there are parameters stated within the docker run command. - ENTRYPOINT instructions are not ignored but instead are appended as command line parameters by treating those as arguments of the command. Real-time example Let’s start with a simple scenario. Say you were to run a docker container from an Ubuntu image. When you run the docker run command it runs an instance of Ubuntu image and exists immediately. If you were to list the running containers you wouldn’t see the container running. If you list all containers including those that are stopped you will see that the new container you ran is in an exited state. ```plain text $ docker run ubuntu$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 10d1a2757900 ubuntu "/bin/bash" 41 seconds ago Exited (0) 40 seconds ago confident_thompson ``` Now, why is that? unlike virtual machines, Containers are not meant to host an operating system. Containers are meant to run a specific task or process such as to host an instance of a web server or application server or a database or simply to carry out some kind of computation or analysis. Once the task is complete the container exits. The container only lives as long as the process inside it is alive. If the web service inside the container is stopped or crashes the container exits. Who defines what process is run within the container? If you look at the Docker file for popular images like NGINX you will see an instruction called CMD which stands for a command that defines the program that will be run within the container when it starts for the NGINX image. What we tried to do earlier was to run a container with a plain Ubuntu operating system. Let’s look at the Docker file for this image you will see that it uses bash as the default command. ```plain text # Pull base image. FROM ubuntu:14.04# Install. RUN \ sed -i 's/# \(.*multiverse$\)/\1/g' /etc/apt/sources.list && \ apt-get update && \ apt-get -y upgrade && \ apt-get install -y build-essential && \ apt-get install -y software-properties-common && \ apt-get install -y byobu curl git htop man unzip vim wget && \ rm -rf /var/lib/apt/lists/*# Add files. ADD root/.bashrc /root/.bashrc ADD root/.gitconfig /root/.gitconfig ADD root/.scripts /root/.scripts# Set environment variables. ENV HOME /root# Define working directory. WORKDIR /root# Define default command. CMD ["bash"] ``` Now bash is not really a process like your web server or database server. It is a shell that listens for inputs from a terminal. If it cannot find a terminal it exits. When we ran the Ubuntu container earlier, docker created a container from the Ubuntu image and launched the bash program. By default, docker doesn’t attach a terminal to a container when it is run. And so the bash program doesn’t find the terminal and so it exists. Since the process that was started when the container was created finished the container exits as well. How do you specify a different command to start a container? One option is to append a command to the docker run command and that way it overrides the default command specified within the image. In our case, I run the docker run ubuntu command with the sleep 10 command as the added option. ```plain text $ docker run ubuntu sleep 10 ``` This way when the container starts it runs the sleep program waits to 10 seconds and then exits. But how do we make that change permanent? Say we want the image to always run the sleep command when it starts. You would then create your own image from the base Ubuntu image and specify the new command. ```plain text FROM ubuntuCMD sleep 10 ``` There are different ways to specify the command either the command simply as is in a shell form or in JSON array format like as follows. ```plain text CMD ["sleep","10"] ``` But remember when you specify in a JSON array format, the first element in the array should be executable. Note that don’t specify the command and parameters together like “sleep 10”. The command and its parameters should be separate elements in the list. So now I build my new image using docker build command and name it as ubuntu-sleeper. I could now simply run the docker run ubuntu-sleeper command and gets the same results. ```plain text $ docker build -t ubuntu-sleeper:1.0.0$ docker run ubuntu-sleeper:1.0.0 ``` It always sleep for 10 seconds and exits. But what if I wish to change the number of seconds it sleeps. Currently, it hardcoded to 10 seconds. As we discussed before, one option is to run the docker run command with the new command appended to it. In this case sleep, 20 and the command that will be run at startup will be sleep 20 but it doesn’t look very good. ```plain text $ docker run ubuntu-sleeper:1.0.0 sleep 20 ``` The name of the image is ubuntu-sleeper in itself is that the container will sleep. So we shouldn’t have to specify the sleep command again. Instead, we would like it to be something like below ```plain text $ docker run ubuntu-sleeper 20 ``` We only want to pass in the number of seconds the container should sleep and sleep command should be invoked automatically and this is where the ENTRYPOINT instructions come into play. ```plain text FROM ubuntuENTRYPOINT ["sleep"] ``` ENTRYPOINT The ENTRYPOINT instruction is like the CMD instruction as in you can specify the program that will be run when the container starts. And whatever you specify on the command line, in this case, 20 will get appended to the ENTRYPOINT (like sleep 20). So the command that will be run when the container starts is sleep 20. So that’s different between ENTRYPOINT and CMD. In the case of CMD instruction, the command line parameters passed will get replaced entirely whereas in the case of ENTRYPOINT the command line parameters will get appended. Now in the second case what if we run the ubuntu-sleeper image command without appending the number of seconds? then the command at startup will be just sleep and you get the error that the operand is missing. So, how do we configure a default value of the command? If one was not specified in the command line that’s where you would use ENTRYPOINT as well as the command instruction. ```plain text FROM ubuntuENTRYPOINT ["sleep"]CMD ["5"] ``` In this case the CMD instruction will be appended to the ENTRYPOINT instruction. So at startup the command would be “sleep 5”, if you didn’t specify any parameters in the command line. If you did then that will override the CMD instruction. Please note that, for this to happen you should always specify the ENTRYPOINT and CMD instructions in a JSON format. Finally what if you feel you really want to modify the ENTRYPOINT during runtime, say from sleep to an imaginary sleep 2.0 command? Well in that case you can override it by using the ENTRYPOINT option in the docker run command. ```plain text $ docker run --entrypoint sleep2.0 ubuntu-sleeper 30 ``` I hope after reading this tutorial, you should have a better understanding of the difference between ENTRYPOINT and CMD. Explore the use of both and experiment with them to find the best solution for you. Conclusion After reading this article, you should have a better understanding of the difference between ENTRYPOINT and CMD. Explore the use of both and experiment with them to find the best solution for you. References: https://phoenixnap.com/kb/docker-cmd-vs-entrypoint https://www.waytoeasylearn.com/learn/cmd-vs-entrypoint/ https://www.baeldung.com/ops/dockerfile-run-cmd-entrypoint https://www.bmc.com/blogs/docker-cmd-vs-entrypoint/#

Visibility

Visible to everyone

Reading Status

Related Bookmarks

My Note


Saved!

Annotations

Agent findings

info Long content (1915 words) has no proposition chunks health · Jun 29
error URL returned 404 health · Jun 29
Export as Markdown

Attachments

+ Annotate selection

Add Annotation