千家信息网

docker entrypoint入口文件详解

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,在编写Dockerfile的时候,包含一个entrypoint配置,该配置的作用是在容器启动之前做一些初始化配置,或者一些自定义的配置等。通常是一个脚本,然后在脚本里配置相关预定义项。这篇文档就详细说
千家信息网最后更新 2026年11月01日docker entrypoint入口文件详解

在编写Dockerfile的时候,包含一个entrypoint配置,该配置的作用是在容器启动之前做一些初始化配置,或者一些自定义的配置等。通常是一个脚本,然后在脚本里配置相关预定义项。这篇文档就详细说一说entrypoint入口文件的编写技巧。

下面以mysql官方镜像中的entrypoint文件docker-entrypoint.sh为例,文件地址为:

docker-entrypoint.sh

set -e

你写的每个脚本都应该在文件开头加上set -e, 这句语句告诉bash如果任何语句的执行结果不是true则应该退出. 这样的好处是防止错误像滚雪球般变大导致一个致命的错误, 而这些错误本应该在之前就被处理掉. 如果要增加可读性, 可以使用set -o errexit, 它的作用与set -e相同

set -o pipefail

设计用途同上, 就是希望在执行错误之后立即退出, 不要再向下执行了. 而 -o pipefail 的作用域是管道, 也就是说在 Linux 脚本中的管道, 如果前面的命令执行出了问题, 应该立即退出

shopt -s nullglob

在使用 Linux 中的通配符时 * ?等 如果没有匹配到任何文件, 不会报 No such file or directory 而是将命令后面的参数去掉执行

if [ "${1:0:1}" = '-' ]; then...

这是一个判断语句, 在官方文件中, 上一行已经给出了注释: if command starts with an option, prepend mysqld

这个判断语句是 ${1:0:1} 意思是判断 $1(调用该脚本的第一个参数), 偏移量0(不偏移), 取一个字符(取字符串的长度)

如果判断出来调用这个脚本后面所跟的参数第一个字符是-中横线的话, 就认为后面的所有字符串都是 mysqld 的启动参数

上面的这个操作类似于 Python 的字符串切片

set -- mysqld "$@"

在上面判断完第一个参数是-开头之后, 紧接着就执行了 set -- mysqld "$@" 这个命令. 使用了 set -- 的用法. set --会将他后面所有以空格区分的字符串, 按顺序分别存储到$1, $2, $3 变量中, 其中新的$@为set --后面的全部内容

举例来说: bash docker-entrypoint.sh -f xxx.conf

在这种情况下, set -- mysqld "$@" 中的 $@ 的值为 -f xxx.conf

当执行完 set -- mysqld "$@" 这条命令后:

  • $1=mysqld
  • $2=-f
  • $3=xxx.conf
  • $@=mysqld -f xxx.conf

可以看到, 当执行 docker-entrypoint.sh脚本的时候后面加了 -x形式的参数之后, $@的值发生的改变, 在原有$@值的基础之上, 在前面又预添加了 mysqld 命令

exec "$@"

几乎在每个docker-entrypoint.sh脚本的最后一行, 执行的都是 exec "$@"命令

这个命令的意义在于你已经为你的镜像预想到了应该有的调用情况, 当实际使用镜像的人执行了你没有预料到的可执行命令时, 将会走到脚本的这最后一行, 去执行用户新的可执行命令

情况判断

上面直接说了脚本的最后一行, 在之前的脚本中, 需要充分的去考虑你自己的脚本可能会被调用的情况. 还是拿 MySQL 官方的 dockerfile 来说, 他判断以下情况:

  • 开头是 - , 认为是参数的情况
  • 开头是 mysqld, 且用户 id 为0 (root 用户) 的情况
  • 开头是 mysqld 的情况
  • 判断完自己应用的所有调用形态之后, 最后应该加上exec "$@" 命令兜底

${mysql[@]}

Shell 中的数组, 直接执行 ${mysql[@]} 会把这个数组当做可执行程序来执行

mysql=( mysql --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" )echo ${mysql[1]}-- output: mysqlecho ${mysql[2]}--output: --protocol=socketecho ${mysql[3]}--output: -urootecho ${mysql[4]}--output: -hlocalhostecho ${mysql[@]}--output: mysql --protocol=socket -uroot -hlocalhost --socket=

exec gosu mysql "$BASH_SOURCE" "$@"

这里的 gosu 命令, 是 Linux 中 sudo 命令的轻量级"替代品"

gosu 是一个 golang 语言开发的工具, 用来取代 shell 中的 sudo 命令. su 和 sudo 命令有一些缺陷, 主要是会引起不确定的 TTY, 对信号量的转发也存在问题. 如果仅仅为了使用特定的用户运行程序, 使用 su 或 sudo 显得太重了, 为此 gosu 应运而生.

gosu 直接借用了 libcontainer 在容器中启动应用程序的原理, 使用 /etc/passwd 处理应用程序. gosu 首先找出指定的用户或用户组, 然后切换到该用户或用户组. 接下来, 使用 exec 启动应用程序. 到此为止, gosu 完成了它的工作, 不会参与到应用程序后面的声明周期中. 使用这种方式避免了 gosu 处理 TTY 和转发信号量的问题, 把这两个工作直接交给了应用程序去完成

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

命令 脚本 情况 用户 参数 程序 文件 字符 应用 应用程序 开头 配置 一行 字符串 语句 错误 作用 官方 镜像 问题 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广州为想互联网科技有限公司 鸠鸠互联网科技 麻工互联网科技 互联网络科技有限公司 智慧科技互联网 金融科技和互联网金融 深圳市运趣互联网科技有限公司 互联网科技公司需要的职位 青岛中康互联网医疗科技有限公司 茂名市互联网科技产业园 互联网科技革命什么开始 知域互联网科技有限公司大骗子 江阴互联网智能科技产品进口 互联网科技大奖都有哪些公司 国大互联网教育科技有限公司工作 互联网公司高科技产品 上海创道互联网络科技有限公司 神州科技互联网有限公司 昆明中奇联合互联网科技 互联网大会出现的黑科技 互联网科技园 亿人帮互联网科技有限公司 互联网科技公司经营范围 世界互联网领先科技成果 成都互联网科技公司 互联网科技股午盘股票涨跌 彤创互联网科技有限公司 山东子淼互联网科技有限公司 科技和互联网行业的特点 第三届互联网大会安防黑科技
0