ENTRYPOINT
Two ways of writing
# exec format ENTRYPOINT ["executable", "param1", "param2"] # shell format ENTRYPOINT command param1 param2
a key
- ENTRYPOINT specifies the default entry command of the image. The entry command will be executed as the root command when starting the container, and all other incoming values will be used as the parameters of the command
- The value of ENTRYPOINT can be overridden by
docker run --entrypoint
- Only the last entry point instruction in Dockerfile will work
ENTRYPOINT and CMD are used together
- When ENTRYPOINT is specified, the meaning of CMD is changed. Instead of directly running its command, the content of CMD is passed to the ENTRYPOINT instruction as a parameter
- In other words, when actually executed, it becomes
<ENTRYPOINT> "<CMD>"
Soul torture
So why should there be entry point after CMD? What are the benefits of this < entry point > "< CMD >"?
Difference between CMD and ENTRYPOINT
CMD # Specify the command to run when the container is started. Commands cannot be appended ENTRYPOINT # Specify the command to run when the container starts, and you can append the command
What do you mean by that? This is actually one of the application scenarios of ENTRYPOINT. Let's look at it below
Test CMD
Write dockerfile file
FROM centos CMD ["ls","-a"]
Build mirror
docker build -f CMD.dockerfile -t test .
Run container
> docker run test . .. .dockerenv bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
Run the container and append the command
> docker run test -l docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
- See the error message that the executable file cannot be found, executable file not found
- Following the image name is command, which will replace the default value of CMD at runtime. Therefore, - l here replaces the original CMD rather than appended to the original ls -a
- And -l is not a command at all, so naturally it can't be found
If you want to add the - i parameter, you must override the ls command
> docker run test ls -a -l total 56 drwxr-xr-x 1 root root 4096 Oct 28 09:36 . drwxr-xr-x 1 root root 4096 Oct 28 09:36 .. -rwxr-xr-x 1 root root 0 Oct 28 09:36 .dockerenv lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin drwxr-xr-x 5 root root 340 Oct 28 09:36 dev drwxr-xr-x 1 root root 4096 Oct 28 09:36 etc drwxr-xr-x 2 root root 4096 Nov 3 2020 home lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64 drwx------ 2 root root 4096 Sep 15 14:17 lost+found drwxr-xr-x 2 root root 4096 Nov 3 2020 media drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt drwxr-xr-x 2 root root 4096 Nov 3 2020 opt dr-xr-xr-x 221 root root 0 Oct 28 09:36 proc dr-xr-x--- 2 root root 4096 Sep 15 14:17 root drwxr-xr-x 11 root root 4096 Sep 15 14:17 run lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin drwxr-xr-x 2 root root 4096 Nov 3 2020 srv dr-xr-xr-x 13 root root 0 Oct 28 09:36 sys drwxrwxrwt 7 root root 4096 Sep 15 14:17 tmp drwxr-xr-x 12 root root 4096 Sep 15 14:17 usr drwxr-xr-x 20 root root 4096 Sep 15 14:17 var
Yes, but this is obviously not the best choice. ENTRYPOINT can solve this problem
Test ENTRYPOINT
Write dockerfile file
FROM centos ENTRYPOINT ["ls","-a"]
Build mirror
docker build -f ENTRYPOINT.dockerfile -t test .
Run the container and append the command
> docker run test -l total 56 drwxr-xr-x 1 root root 4096 Oct 28 09:38 . drwxr-xr-x 1 root root 4096 Oct 28 09:38 .. -rwxr-xr-x 1 root root 0 Oct 28 09:38 .dockerenv lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin drwxr-xr-x 5 root root 340 Oct 28 09:38 dev drwxr-xr-x 1 root root 4096 Oct 28 09:38 etc drwxr-xr-x 2 root root 4096 Nov 3 2020 home lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64 drwx------ 2 root root 4096 Sep 15 14:17 lost+found drwxr-xr-x 2 root root 4096 Nov 3 2020 media drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt drwxr-xr-x 2 root root 4096 Nov 3 2020 opt dr-xr-xr-x 207 root root 0 Oct 28 09:38 proc dr-xr-x--- 2 root root 4096 Sep 15 14:17 root drwxr-xr-x 11 root root 4096 Sep 15 14:17 run lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin drwxr-xr-x 2 root root 4096 Nov 3 2020 srv dr-xr-xr-x 13 root root 0 Oct 28 09:38 sys drwxrwxrwt 7 root root 4096 Sep 15 14:17 tmp drwxr-xr-x 12 root root 4096 Sep 15 14:17 usr drwxr-xr-x 20 root root 4096 Sep 15 14:17 var
The second application scenario of ENTRYPOINT
- Starting the container is to start the main process, but some preparations may be required before starting the main process. For example, mysql may require some database configuration and initialization, which should be solved before the final mysql server runs
- You may also want to avoid using the root user to start the service, so as to improve security. Before starting the service, you need to perform some necessary preparations as root, and finally switch to the service user to start the service
- These preparations have nothing to do with the container CMD. No matter what the CMD is, a preprocessing work needs to be carried out in advance. In this case, a script can be written and put into ENTRYPOINT for execution, and the script will take the received parameters (i.e. < CMD >) as commands and execute them at the end of the script
Official image redis
FROM alpine:3.4 ... RUN addgroup -S redis && adduser -S -G redis redis ... ENTRYPOINT ["docker-entrypoint.sh"] EXPOSE 6379 CMD [ "redis-server" ]
docker-entrypoint.sh
#!/bin/sh ... # allow the container to be started with `--user` if [ "$1" = 'redis-server' -a "$(id -u)" = '0' ]; then find . \! -user redis -exec chown redis '{}' + exec gosu redis "$0" "$@" fi exec "$@"
The content of the script is judged according to the content of CMD. If it is a redis server, switch to the redis user identity to start the server. Otherwise, it is still executed as root
[root@poloyy ~]# docker run -it redis id uid=0(root) gid=0(root) groups=0(root) # Directly into the container [root@poloyy ~]# docker run -it redis root@565f89976d63:/#