Execute with start#

You can specify in the dockerfile what the container should do when it runs. There are two dockerfile directives that allow this: ENTRYPOINT and CMD.

Entrypoint vs CMD#

In a Dockerfile, ENTRYPOINT and CMD are both used to specify the command that should be run when a container starts. However, they serve different purposes and have different behaviors.

CMD

  • Purpose: To provide defaults for an executing container.

  • Overriding: The command defined with CMD can be overridden by specifying a different command at the end of the docker run command.

ENTRYPOINT

  • Purpose: To define a command that will always run when the container starts.

  • Overriding: The command defined with ENTRYPOINT is not easily overridden. You can still provide arguments to the ENTRYPOINT via the docker run command, but the specified command itself remains the same.


For example consider dockerfile that declares ENTRY POINT echo. And we’ll run containers based on those dockerfile with echo 10 command.

cat << EOF > dockerfile
FROM alpine
ENTRYPOINT ["echo"]
EOF

docker build -t entr_vs_cmd . &> /dev/null
docker run --rm entr_vs_cmd echo 10
docker rmi entr_vs_cmd &> /dev/null
echo 10

As a result, we got the output echo 10. To understand what happened, let’s look closer: echo was specified in the ENTRYPOINT, and the command echo 10 provided in docker run was simply appended to it. SO finally we got command echo "echo 10" executed.

Almost same example just using CMD instead of ENTRYPOINT.

cat << EOF > dockerfile
FROM alpine
CMD ["echo"]
EOF

docker build -t entr_vs_cmd . &> /dev/null
docker run --rm entr_vs_cmd echo 10
docker rmi entr_vs_cmd &> /dev/null
10

Just 10 as ouput. Command echo was just replaced by command specified during docker run.

Cleaning artefacts from the experiment.

rm dockerfile

ENTRYPOINT and CMD#

By combining ENTRYPOINT and CMD in a single Dockerfile, you can achieve the following configuration: use ENTRYPOINT to specify the fixed part of the command and CMD for the part that can be changed.


The following example demonstrates a Dockerfile that creates an image with a Python container. By using ENTRYPOINT ["python3", "-c"], the container is set up to execute the Python interpreter. The CMD ["print(\"I'm a Python interpreter\")"] specifies the default command to run, which in this case, executes python3 -c "print(\"I'm a Python interpreter\")" when the container starts. The part within CMD can be replaced with any other command as needed.

cat << EOF > dockerfile
FROM python:3.10-alpine
ENTRYPOINT ["python3", "-c"]
CMD ["print(\"I'm a python interpreter\")"]
EOF

docker build -t test_image . &> /dev/null

docker run --rm test_image
docker run --rm test_image "print(666+444)"

docker rmi test_image &> /dev/null
rm dockerfile &> /dev/null
I'm a python interpreter
1110

So we got output for the default case and for the python command print(666+444).

Several CMD/ENTRYPOINT#

If there are multiple CMD or ENTRYPOINT directives in the docker file, only the last one will be used.


The following example shows a dockerfile that contains many CMD and ENTRYPOINT directives, and prints counting messages. Containers run from this dockerfile will only print options with high counts - it’s a signal that there are only last options where used.

cat << EOF > dockerfile
FROM alpine

ENTRYPOINT ["echo", "entr 0"]
ENTRYPOINT ["echo", "entr 1"]
CMD ["cmd 2"]
ENTRYPOINT ["echo", "entr 3"]
ENTRYPOINT ["echo", "entr 4"]
CMD ["cmd 5"]
ENTRYPOINT ["echo", "entr 6"]
CMD ["cmd 7"]
ENTRYPOINT ["echo", "entr 8"]
CMD ["cmd 9"]
EOF

docker build -t test_image . &> /dev/null
docker run --rm test_image

docker rmi test_image &> /dev/null
rm dockerfile
entr 8 cmd 9