Closed11

nginxコンテナのdocker-entrypoint.shは何をしているのか

not75743not75743

これはなに?

nginxの公式コンテナイメージを使用しており、
起動時にシェルスクリプトを実行したいときは、/docker-entrypoint.dに実行したいシェルスクリプトを格納すれば動作します。

ではなぜ/docker-entrypoint.dに格納するのでしょうか。
同じ階層にある/docker-entrypoint.shに秘密が書かれてそうなので読んでみました。

not75743not75743

コード

entrypoint_log() {
    if [ -z "${NGINX_ENTRYPOINT_QUIET_LOGS:-}" ]; then
        echo "$@"
    fi
}

役割①

nginxイメージの説明に記載がありました。
Ver1.19.0以降はentrypointの詳しいログがデフォルトで有効になっており、
NGINX_ENTRYPOINT_QUIET_LOGS環境変数を設定するとそれを抑制できるようです。

Since version 1.19.0, a verbose entrypoint was added. It provides information on what's happening during container startup. You can silence this output by setting environment variable NGINX_ENTRYPOINT_QUIET_LOGS:

https://hub.docker.com/_/nginx

役割②

entrypoint_log関数を作成しています。
NGINX_ENTRYPOINT_QUIET_LOGSの文字列の長さが0(空)であれば、渡された文字列を出力します。

例えばこの文字列が出力されるわけですね

 entrypoint_log "$0: /docker-entrypoint.d/ is not empty, will attempt to perform configuration"
not75743not75743

コード

if [ "$1" = "nginx" -o "$1" = "nginx-debug" ]; then
...
fi

役割

docker-entrypoint.shの第一引数がnginxnginx-debugであれば処理が進むということですね。
CMDとかで書き換えると設定が読み込まれないのか...

ifの中の-oオプション

or条件を表すそうです。引数の候補が複数あるのに対応できるんですね
man [で見れます

EXPRESSION1 -o EXPRESSION2
either EXPRESSION1 or EXPRESSION2 is true

not75743not75743

コード

    if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -maxdepth 1 -type f -print -quit 2>/dev/null | read v; then
    ...
    else
        entrypoint_log "$0: No files found in /docker-entrypoint.d/, skipping configuration"
    fi

役割

/docker-entrypoint.d/配下にファイルがあれば処理を進め、なければelseに飛びます
readで標準出力を変数に格納しているのは余計なログを出さないため?

not75743not75743

コード

        entrypoint_log "$0: /docker-entrypoint.d/ is not empty, will attempt to perform configuration"

        entrypoint_log "$0: Looking for shell scripts in /docker-entrypoint.d/"
        find "/docker-entrypoint.d/" -follow -type f -print | sort -V | while read -r f; do
		# 処理
        done

役割①

/docker-entrypoint.d/配下にファイルが存在する場合、entrypoint_log関数を実行します。

役割②

/docker-entrypoint.d/のファイルをfindで検索し、結果をreadで1つずつ読み込みます。
読み込んだファイルに処理を実行し、それをファイル数分繰り返します。

not75743not75743

コード

            case "$f" in
                *.envsh)
                    if [ -x "$f" ]; then
                        entrypoint_log "$0: Sourcing $f";
                        . "$f"
                    else
                        # warn on shell scripts without exec bit
                        entrypoint_log "$0: Ignoring $f, not executable";
                    fi
                    ;;
                *.sh)
                    if [ -x "$f" ]; then
                        entrypoint_log "$0: Launching $f";
                        "$f"
                    else
                        # warn on shell scripts without exec bit
                        entrypoint_log "$0: Ignoring $f, not executable";
                    fi
                    ;;
                *) entrypoint_log "$0: Ignoring $f";;
            esac

役割

先述のreadで読み込んだファイル名によって処理を変えます。

ファイル名が*.envshの場合

ファイルが実行可能であれば. <ファイル名>(ドットコマンド)を実行し、変数を読み込む。
実行不可である場合その旨をentrypoint_logで出す。

ファイル名が*.shの場合

ファイルが実行可能であれば実行する。
実行不可である場合その旨をentrypoint_logで出す。

それ以外

entrypoint_log "$0: Ignoring $f"を実行

not75743not75743

簡潔にまとめ

  • 詳細ログをみたいときはNGINX_ENTRYPOINT_QUIET_LOGSを設定する
  • 実行権限を与えたスクリプトを/docker-entrypoint.d/に配置すれば、/docker-entrypoint.shで実行してくれる
not75743not75743

所感

シェルスクリプトを読む良い練習になりました。
nginxコンテナをいじる際はこのページを参照する。

このスクラップは2023/02/02にクローズされました