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 thedocker 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 theENTRYPOINT
via thedocker 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