When writing a Dockerfile, it contains an entrypoint configuration. The function of this configuration is to make some initialization configurations, or some custom configurations, etc. before the container is started. Usually it is a script, and then the relevant predefined items are configured in the script. This document will talk about the writing skills of entrypoint entry files in detail.
Here is an example of the entrypoint file in the official mysql image, with the file address:
set -e
Each script you write should add set -e at the beginning of the file. This statement tells bash to exit if the execution result of any statement is not true. This benefit is to prevent errors from becoming larger like snowballs and causing a fatal error, which should have been processed before. If you want to increase readability, you can use set -o errexit, which works the same as set -e
set -o pipefail
The design purpose is the same as above, which means that you hope to exit immediately after the execution error and do not execute downward again. The scope of -o pipefail is a pipeline, that is, the pipeline in Linux scripts. If there is a problem with the execution of the previous command, you should exit immediately
shopt -s nullglob
When using wildcards in Linux *? etc. If no file is matched, no such file or directory will be reported instead of executing the parameters after the command.
if [ "${1:0:1}" = '-' ]; then...
This is a judgment statement. In the official file, the previous line has given a comment: if command starts with an option, prepend mysqld
This judgment statement is ${1:0:1}
Meaning is to judge $1
(Call the first parameter of the script), offset 0 (not offset), take one character (take the length of the string)
If it is determined that the first character of the parameter followed by calling this script is - mid-horizontal line, it is considered that all the following strings are the startup parameters of mysqld
The above operation is similar to Python's string slice
set -- mysqld "$@"
After judging above that the first parameter is -, Immediately execute the command set -- mysqld "$@". The usage of set -- is used. set -- will store all the strings distinguished by spaces after it into the $1, $2, and $3 variables in order, where the new $@ is set -- all the contents after it.
For example:bash -f
in this case,set -- mysqld "$@"
The value of $@ in -f
After executing the command set -- mysqld "$@":
- $1=mysqld
- $2=-f
- $3=
- $@=mysqld -f
You can see that when the script is executed, the change of the value of $@ is added on the basis of the original $@ value and the mysqld command is pre-added in front.
exec "$@"
On almost the last line of each script, the exec "$@" command is executed
The meaning of this command is that you have already predicted the call situation for your image. When the person who actually uses the image executes the executable command you did not expect, he will go to the last line of the script to execute the user's new executable command
Qualification of situation
The above directly talks about the last line of the script. In the previous script, you need to fully consider the situation where your own script may be called. Take MySQL's official dockerfile as an example, which judges the following situations:
- The beginning is - , which is considered to be a parameter
- The situation where mysqld starts with user id is 0 (root user)
- The beginning is mysqld
- After judging all the calling forms you applied, you should add the exec "$@" command to guarantee the bottom line
${mysql[@]}
The array in the shell, directly executing ${mysql[@]} will execute this array as an executable program.
mysql=( mysql --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" ) echo ${mysql[1]} -- output: mysql echo ${mysql[2]} --output: --protocol=socket echo ${mysql[3]} --output: -uroot echo ${mysql[4]} --output: -hlocalhost echo ${mysql[@]} --output: mysql --protocol=socket -uroot -hlocalhost --socket=
exec gosu mysql "$BASH_SOURCE" "$@"
The gosu command here is a lightweight "replacement" of the sudo command in Linux
gosu is a golang language development tool used to replace the sudo command in the shell. The su and sudo commands have some flaws, mainly because they will cause uncertain TTY and there are problems with forwarding semaphores. If you just want to run a program with a specific user, using su or sudo seems too heavy, so gosu came into being.
gosu directly borrows the principle of starting an application in a container by libcontainer, and uses /etc/passwd to handle the application. gosu first finds the specified user or user group, and then switches to that user or user group. Next, use exec to start the application. So far, gosu has done its work and will not participate in the declaration cycle after the application. This method avoids the problem of gosu handling TTY and forwarding semaphores, and handing these two tasks directly to the application to complete.
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.