Introduction

While creating a Dockerfile, we have two similar yet confusing key instructions, CMD and ENTRYPOINT, which have a pivotal role in determining the behavior of a container. In this blog, we will explain Docker CMD and ENTRYPOINT with the help of examples.

We will be using a simple Python application for the example and write a Dockerfile to illustrate the differences between both instructions; we will also be looking at how they impact the execution and see which is more suitable for us. By the end of the blog, you will clearly understand which instruction to utilize in your Dockerfile.

Below is the code for the Python application server_one.py that we will be using in this blog.

# server_one.py
from flask import Flask
server = Flask(__name__)

@server.route('/')
def hello_world():
    return 'Hello, Docker! This is server 1'

if __name__ == '__main__':
    server.run(host='0.0.0.0', port=5000)

Let’s dive into it!

What is CMD?

CMD instruction in Docker is used to define a default command that is to be executed when we run our container, but it can be easily overridden by passing the arguments at the time of container startup.

Things will get clearer once you read the example. 

We will be writing a Dockerfile for our server_one.py application, a simple web server that uses port 5000.

# Dockerfile using CMD
FROM python:alpine3.19

COPY . .

RUN pip install -r requirements.txt

CMD ["python", "/server_one.py"]

Here is our Docker file to containerize the Python application. Let’s focus on the CMD part; here, we are setting a default command that will get executed each time we run our container. This command is similar to python server_one.py, which you use to run any typical Python application.

Now, let’s build this Docker file to create our image.

#Command to build docker image for our server
docker build -t server-cmd.
#Check is image is build
docker images

This command builds our docker image, so let’s run this.

#To run our docker image
docker run -p 5000:5000 server-cmd

In the above command, I have specified the port to be 5000 as our server is using port 5000. And yes our server successfully runs.

Will replace it with og



We are using the EC2 instance for this demo, so you will see the IP address: port of the machine in the screenshots or the video. If you are using localhost, it might be localhost: port.

But as we know, CMD is a default command and can be easily overridden. To demonstrate this, let’s create another server: server_two.py and see if we can run this server instead of our server_one. We have configured port 3000 for this server.

# server_two.py
from flask import Flask
serverTwo = Flask(__name__)

@server.route('/')
def hello_world():
    return 'Hello, Docker! This is server 2'

if __name__ == '__main__':
    serverTwo.run(host='0.0.0.0', port=3000)

This time, while running the container, we will be giving the command to run server_two.

#Focus in the end argument 
docker run -p 3000:3000 server-cmd python server_two.py

Let’s see what it did to this command when it was executed.

So yes, it executed and ran the server_two instead of server_one.

See, this is how easy it is to override the CMD instruction. 

Let’s take one more example, this time simpler. Instead of running another server, let’s try to print something.

docker run -p 5000:5000 server-cmd echo 'CloudZenia Rocks!!'

As expected, we got the response as ‘CloudZenia Rocks!!’; so we can see that we can easily override CMD using docker run or while running the docker images.

Now that you have clearly understood what is CMD. Let’s look at what Entrypoint is.Note: CMD can be written the exec form CMD [“executable”, “param1”, “param2”] and CMD command param1 param2 shell form, same for the ENTRYPOINT, we have exec form as ENTRYPOINT [“executable”, “param1”, “param2”] and shell form as ENTRYPOINT command param1 param2.

What is Entrypoint In Docker?

ENTRYPOINT instruction in Docker is used to set the primary command, which means that this command will always get executed when the container is started. Like CMD, it can also be overridden, but we need to use the –entrypoint flag for this.

It is generally used when you want to fix the main command for your application. 

Let’s look into our example for a better understanding of what is an Entrypoint in Docker.

# Dockerfile using ENTRYPOINT
FROM python:alpine3.19

COPY . .

RUN pip install -r requirements.txt

ENTRYPOINT ["python", "/server_one.py"]

The above Dockerfile is similar to the one we saw in the case of CMD; the ENTRYPOINT instruction here is also similar, but it sets the command as the primary or permanent command until we use the –entrypoint flag.

Now, let’s try to do a similar thing as we did in the case of CMD; first, let’s build the docker image using –

#Build docker image
docker build -t server-entrypoint.
#Check for the images
docker images

Once our image is successfully built, it’s time to run and check if we can override the command as provided using the ENTRYPOINT instruction.

Check whether the image is running without additional arguments using docker run -p 5000:5000 server-entry point for this case, and you can see that, yes, it is running.

Now we’ll modify the docker run command to this –

# Same command that we used in the case of CMD
docker run -p 3000:3000 server-entry point python server_two.py

This time, we got the output as –

In this case, our server_one continues to run, this is because we cannot override the command while using the ENTRYPOINT instruction.

Let’s try this using another example –

# Using echo as the argument 
docker run -p 5000:5000 server-entry point echo 'CloudZenia Rocks Again!!'

We can see that although we have passed the argument, server_one is still getting executed.

By now, it might have been clearer what is CMD and what is ENTRYPOINT.

The selection of these two must be based on your requirements and how you want your container to behave. If you want to enforce a fixed main command and allow users to provide only arguments, then use ENTRYPOINT and if you want to provide default values for the main command that users can easily override, use CMD.

Note: There is a difference between docker run and ENTRYPOINT. Docker run provisions a new container each time it is executed, but ENTRYPOINT does not.

Conclusion

In this blog, we saw the two important key instructions used in Dockerfile to customize the behavior of the container and what is the difference between the two. We hope that by now, you can easily differentiate between CMD and ENTRYPOINT. We also saw major differences using practical examples that would have given a clear understanding of how to use these instructions properly and what their effects are.

We hope this blog helped you. Try using CMD and ENTRYPOINT instructions by yourself to get a deeper understanding of the topic.

For more such information, refer to our other CloudZenia Blogs. We have covered all the insights you might want to get cleared here.

Thanks for reading the blog. Happy Learning!

Feb 13, 2024