mysql 5.6 Dockerfile分析

代码路径:
https://github.com/docker-library/mysql/tree/master/5.6
commit id:
883703dfb30d9c197e0059a669c4bb64d55f6e0d

Dockerfile分析

4 RUN groupadd -r mysql && useradd -r -g mysql mysql

增加用户组mysql,并且增加一个用户mysql到mysql用户组
查看所有用户:cat /etc/passwd
查看所有用户组:cat /etc/group
查看用户属于哪一个组:groups mysql

10         && wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture)" \

获取平台的类型,如i386等

11         && wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture).asc" \

.asc是用来校验文件没被更改过

12         && export GNUPGHOME="$(mktemp -d)" \

生成临时路径,仅仅是一个名字,没有实际去创建这个路径

13         && gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \

接收公钥

14         && gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \

--batch:静默模式,不请求用户输入,用公钥gousu.asc校验gosu

17         && gosu nobody true \

切换到nobody用户

45 RUN { \
 46                 echo mysql-community-server mysql-community-server/data-dir select ''; \
 47                 echo mysql-community-server mysql-community-server/root-pass password ''; \
 48                 echo mysql-community-server mysql-community-server/re-root-pass password ''; \
 49                 echo mysql-community-server mysql-community-server/remove-test-db select false; \
 50         } | debconf-set-selections \
 51         && apt-get update && apt-get install -y mysql-server="${MYSQL_VERSION}" && rm -rf /var/lib/apt/lists/* \

无人值守安装时,预置所有待输入的参数,可以先找出安装过程中需要用户输入的信息

root@ubuntu:~# debconf-show  mysql-server-5.7
* mysql-server/root_password_again: (password omitted)
* mysql-server/root_password: (password omitted)
* mysql-server/password_mismatch:
  mysql-server-5.7/really_downgrade: false
  mysql-server-5.7/nis_warning:
  mysql-server-5.7/postrm_remove_databases: false
  mysql-server/no_upgrade_when_using_ndb:
  mysql-server-5.7/start_on_boot: true
57         && find /etc/mysql/ -name '*.cnf' -print0 \
58                 | xargs -0 grep -lZE '^(bind-address|log)' \
59                 | xargs -rt -0 sed -Ei 's/^(bind-address|log)/#&/' \

找到所有.cnf,然后显示在同一行
xargs 默认是以空白字符 (空格, TAB, 换行符) 来分割记录的, 因此文件名 ./file 1.log 被解释成了两个记录 ./file 和 1.log,为了解决此类问题,让 find 在打印出一个文件名之后接着输出一个 NULL 字符 ('\0') 而不是换行符, 然后再告诉 xargs 也用 NULL 字符来作为记录的分隔符(它等价于xargs -d"\0"),这就是 find 的 -print0 和 xargs 的 -0 的来历
-r:如果传给xargs的参数是空的,则不执行后面的命令
-t:执行命令前,先打印命令
sed -i 's/^http/#&/' baobao.txt:把以http开头的行注释掉

docker-entrypoint.sh分析

2 set -eo pipefail

-e:有错误立刻退出
-o pipefail:表示在管道连接的命令序列中,只要有任何一个命令返回非0值,则整个管道返回非0值,即使最后一个命令返回0

3 shopt -s nullglob

关闭通配符,路径传递时,通配符路径直接失效

5 # if command starts with an option, prepend mysqld
6 if [ "${1:0:1}" = '-' ]; then
7         set -- mysqld "$@"
8 fi

$@:代表所有的参数列表
$1:第一个参数,$2第二个参数,以此类推
它的效果是:如果参数中含有-选项,则将选项和mysqld拼接起来(mysqld -x abc -y efg)
举个例子:

# [root@CentOS tmp]# cat test.sh 
# #!/bin/bash
# set -e
# if [ "${1:0:1}" = '-' ]; then
#         set -- mysqld "$@"
# fi
# echo '$@='$@
# echo '$1='$1
# echo '$2='$2
# echo '$3='$3
# [root@CentOS tmp]# sh test.sh -p 22 -h 192.168.31.20
# $@=mysqld -p 22 -h 192.168.31.20
# $1=mysqld
# $2=-p
# $3=22
11 wantHelp=
12 for arg; do
13         case "$arg" in
14                 -'?'|--help|--print-defaults|-V|--version)
15                         wantHelp=1
16                         break
17                         ;;
18         esac
19 done

如果执行脚本跟了参数(这些参数 -'?'|--help|--print-defaults|-V|--version),将将wantHelp=1

28         local def="${2:-}"

如果没有有第2个参数,def就是空值,有第2个参数,则def=$2

37                 val="$(< "${!fileVar}")"

将文件的内容读出来,放到变量val中

44         toRun=( "$@" --verbose --help --log-bin-index="$(mktemp -u)" )

$@:所有参数,还没研究透

45         if ! errors="$("${toRun[@]}" 2>&1 >/dev/null)"; then
46         cat >&2 <<-EOM
47 
48             ERROR: mysqld failed while attempting to check config
49             command was: "${toRun[*]}"
50 
51             $errors
52         EOM
53         exit 1
54     fi

2>&1 > /dev/null:错误输出重定向到标准输出,然后一起全部重定向到/dev/null
cat > &2 << -EOM
xxx
EOM
把xxx显示在标准错误输出流,也就是屏幕上
${toRun[@]}:表示所有参数,举个例子

root@ubuntu:~# toRun=("ls -lh" /tmp)
root@ubuntu:~# ${toRun[0]}          
total 24K
drwxr-xr-x 2 root root 4.0K Nov 21 19:28 5.6
-rw-r--r-- 1 root root   10 Oct 29 01:44 baidu_verify_ZbHchxuu6r.html
-rw-r--r-- 1 root root    6 Nov 20 22:06 baobao.txt
-rw-r--r-- 1 root root  144 Nov  3 23:42 push_2_baidu.sh
-rw-r--r-- 1 root root  114 Nov  3 23:45 push_2_baidu.txt
drwxr-xr-x 5 root root 4.0K Nov 19 15:24 WorkSpace
root@ubuntu:~# ${toRun[@]}          
total 36K
srwxr-xr-x 1 root root    0 Nov 18 15:22 Aegis-
drwxr-xr-x 2 root root 4.0K Nov 18 15:22 hsperfdata_root
drwx------ 2 root root 4.0K Nov 20 21:14 tmp.hlu8E2o9Jv
drwx------ 2 root root 4.0K Nov 20 21:14 tmp.IruuIKsj05
drwx------ 2 root root 4.0K Nov 20 21:14 tmp.IXSSh14ros
drwx------ 2 root root 4.0K Nov 20 21:14 tmp.JG1ztjKAXQ
drwx------ 2 root root 4.0K Nov 20 21:14 tmp.KEdUeRMF96
drwx------ 2 root root 4.0K Nov 20 21:14 tmp.qjR9ulWt4b
drwx------ 2 root root 4.0K Nov 20 21:14 tmp.Qr9gCqSKGC
drwx------ 2 root root 4.0K Nov 20 21:14 tmp.V7kDngPX97

${toRun[0]} <---> ls -lh
${toRun[@]} <---> ls -lh /tmp

60 _get_config() {
61     local conf="$1"; shift
62     "$@" --verbose --help --log-bin-index="$(mktemp -u)" 2>/dev/null | awk '$1 == "'"$conf"'" { print $2; exit }'
63 }

shift:依次向左移位
awk '$1 == "'"$conf"'" { print $2; exit }':以空格作为分隔符,如果模式空间的第1列等于conf,则打印第2列的内容

65 # allow the container to be started with `--user`
66 if [ "$1" = 'mysqld' -a -z "$wantHelp" -a "$(id -u)" = '0' ]; then
67     _check_config "$@"
68     DATADIR="$(_get_config 'datadir' "$@")"
69     mkdir -p "$DATADIR"
70     chown -R mysql:mysql "$DATADIR"
71     exec gosu mysql "$BASH_SOURCE" "$@"
72 fi

-a:与或非得与逻辑,表示同时满足条件
-z:非空
$(id -u):当前用户的id
exec gosu mysql "$BASH_SOURCE" "$@":用mysql用户去执行(不另外开辟线程)

91         mysql_install_db --datadir="$DATADIR" --rpm --keep-my-cnf

--rpm --keep-my-cnf:保留用户my.cnf文件(启动时会用到,没有的话读取默认配置)

100         for i in {30..0}; do
101             if echo 'SELECT 1' | "${mysql[@]}" &> /dev/null; then
102                 break
103             fi
104             echo 'MySQL init process in progress...'
105             sleep 1
106         done

for i in {30..0}:倒计时30秒,30 29 28 。。。
if echo 'SELECT 1':如果屏幕打印1,也就是当倒计时到1的时候

128             read -r -d '' rootCreate <<-EOSQL || true

-r:
-d:
|| true:

你可能感兴趣的:(mysql 5.6 Dockerfile分析)