Link to the original text of this article: https://blog.csdn.net/xzk9381/article/details/114635083
In the process of writing a Dockerfile, you need to use CMD or ENTRYPOINT to specify the command when the container is running. From a functional point of view, the functions of these two commands are almost duplicated. In general, using one of the commands can meet most of the needs. Next, let me talk about the difference between CMD and ENTRYPOINT.
One, exec and shell mode
The first thing to be clear is that both CMD and ENTRYPOINT instructions can use exec and shell modes. These two modes are mainly used to designate different processes in the container as the No. 1 process.
1. exec mode
As mentioned earlier, exec and shell modes will designate different processes as the number 1 process in the container. When using the exec mode, the command specified in the Dockerfile is the No. 1 process in the container, for example:
FROM ubuntu
CMD ["top"]
Use the Dockerfile to build the image and run it. Enter the container and use the ps command to find that the process No. 1 is the top command.
Since the exec mode does not execute commands through the shell, the environment variables cannot be obtained when using this mode:
FROM ubuntu
CMD ["echo","${HOSTNAME}"]
After building the image and running it, you can find that the content in the log output is still ${HOSTNAME}, and it is not converted to the corresponding value.
But if you use the exec mode to execute the shell, you can get the environment variables:
FROM ubuntu
CMD ["/bin/bash","-c","echo ${HOSTNAME}"]
It should be noted that the use of exec mode requires double quotes to wrap the parameters.
2. Shell mode
When using the shell mode, docker will execute task commands in the form of /bin/sh -c "task command". In other words, process No. 1 in the container is not a task process but a bash process:
FROM ubuntu
CMD top
After the image is built and run, the ps command can be used to find that the number 1 process is /bin/sh -c top.
Two, CMD command
The CMD command is used to provide the default startup command for the container. There are three ways to use this command, the most commonly used one is to provide default parameters for ENTRYPOINT, and the other two are the shell and exec modes mentioned above:
CMD ['param1','param2']
It should be noted that when using the docker run command, if the startup command is manually specified, the command will override the CMD instruction in the Dockerfile. And the parameters specified through the command line will not be passed to the CMD command.
Three, ENTRYPOINT command
The ENTRYPOINT command is also used to provide the default startup command for the container. There are two ways to use this command, namely the aforementioned shell mode and exec mode. The basic usage is the same as the CMD command, but it also contains some special usages.
1. Example 1: When specifying ENTRYPOINT to use exec mode, the parameters specified on the command line will be added to the parameter list of the ENTRYPOINT specified command
FROM ubuntu
ENTRYPOINT ["top","-b"]
After making the image, use the following command to start the container:
docker run --rm test:v1 -c
Enter the container to view the process No. 1, you can find that the process is top -b -c
, which means that the parameters in the command line have been added to the parameter list.
2. Example 2: Use the CMD command to specify the default parameter list
FROM ubuntu
ENTRYPOINT ["top","-b"]
CMD ["-c"]
After making the image, use the following command to start the container (without command line parameters):
docker run --rm test:v1
Enter the container to view the process No. 1, you can find that the process is top -b -c
. If the parameters are specified when starting the container:
docker run --rm test:v1 -n 1
Then the -n 1 parameter will overwrite the parameter in CMD, and the command actually executed in the container is top -b -n 1
.
3. Example 3: When specifying ENTRYPOINT to use shell mode, command line parameters will be completely ignored
FROM ubuntu
ENTRYPOINT echo ${HOSTNAME}
After making the image, use the following command to start the container:
docker run --rm test:v1 ls
You can find that the output is the host name, not the result of the ls command.
4. Example 4: Override the default ENTRYPOINT command
When starting the container, explicitly specify the --entrypoint parameter to override the default ENTRYPOINT command:
docker run --rm test:v1 --entrypoint echo ${HOME}
Fourth, understand how to use CMD and ENTRYPOINT together
Regarding how to use CMD and ENTRYPOINT together, the official website gives the following instructions:
- Dockerfile should specify at least one of
CMD
orENTRYPOINT
commands. ENTRYPOINT
should be defined when using the container as an executable.CMD
should be used as a way of defining default arguments for anENTRYPOINT
command or for executing an ad-hoc command in a container.CMD
will be overridden when running the container with alternative arguments.
The table below shows what command is executed for different ENTRYPOINT
/ CMD
combinations:
No ENTRYPOINT | ENTRYPOINT exec_entry p1_entry | ENTRYPOINT [“exec_entry”, “p1_entry”] | |
---|---|---|---|
No CMD | error, not allowed | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry |
CMD [“exec_cmd”, “p1_cmd”] | exec_cmd p1_cmd | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry exec_cmd p1_cmd |
CMD [“p1_cmd”, “p2_cmd”] | p1_cmd p2_cmd | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry p1_cmd p2_cmd |
CMD exec_cmd p1_cmd | /bin/sh -c exec_cmd p1_cmd | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd |
In summary, it is the following points:
- If ENTRYPOINT uses shell mode, the CMD command will be ignored.
- If ENTRYPOINT uses the exec mode, the content specified by CMD is appended as the parameter of the ENTRYPOINT specified command.
- If ENTRYPOINT uses exec mode, CMD should also use exec mode.
Link to the original text of this article: https://blog.csdn.net/xzk9381/article/details/114635083