こんにちは、エンジニアの友田です。 MLエンジニアを目指しています。
前回のDockerコンテナのプロセス検証でこんな疑問を抱きました。
さて皆さん。コンテナを起動したら手動で停止するまで動いていませんか?なぜか気になりませんか?ENTRYPOINT命令を指定しなくても・・・・
2つの疑問が生じました。
-
プロセスが起動し続けている理由
-
デフォルトプロセスのENTROYPOINT命令はどこで指定されいているのか
先に結論をお伝えします。
-
=> nodeコマンドのプロセスが起動しているから
-
=> node:18のベースイメージで指定されている
結論までの道筋を解説します。一緒に確認しましょう。
注意事項
Dockerを使ったことがある方向けです。
事前の準備
Dockerfileを準備します。
1 2 3 4 |
FROM node:18 WORKDIR /src # ENTRYPOINT ["node"] ←コメントアウト |
1 2 3 4 5 6 7 |
version: '3' services: node: build: . volumes: - ./src:/src |
ファイルの説明は、前回の記事を参照ください。前回との違いは、ENTRYPOINT命令をコメントアウトしました。
コンテナを起動する
1 2 |
docker-compose run node |
コンテナが立ち上がります。下記コマンドでプロセスを確認しましょう。
1 2 |
docker ps |
プロセスが立ち上がっています。ENTRYP0INT命令をコメントアウトしたのに・・・なぜでしょうか
プロセスの詳細を確認する
docker psコマンドの出力を確認します。
赤枠のCOMMAND行が、ENTRYPOINT命令で指定したコマンドです。”docker-entrypoint.sh”スクリプトが指定されています。
どこに書かれているでしょうか?
Dockerfile1行目のFROM命令に注目しましょう。node:18のベースイメージを指定しています。
このイメージはOSSです。ソースコードを確認しましょう。
node:18イメージのソースコードを確認する
行末2行を表示します。ソースコードの全てはこちらです。
1 2 |
ENTRYPOINT ["docker-entrypoint.sh"] CMD ["node"] |
ENTRYPOINT命令を確認できました。”docker-entrypoint.sh”が指定されています。つまり、疑問の1つ「デフォルトプロセスのENTROYPOINT命令はどこで指定されいているのか」の回答は、node:18のイメージで指定されているです。
docker-entrypoint.shスクリプトを確認する
疑問の1つは解決されました。ただし、「プロセスが起動し続けている理由」が解決されていません。そこで、”docker-entrypoint.sh”を確認しましょう。OSSなのでソースコードを確認できます。
1 2 3 4 5 6 7 8 9 10 11 |
#!/bin/sh set -e # Run command with node if the first argument contains a "-" or is not a system command. The last # part inside the "{}" is a workaround for the following bug in ash/dash: # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=874264 if [ "${1#-}" != "${1}" ] || [ -z "$(command -v "${1}")" ] || { [ -f "${1}" ] && ! [ -x "${1}" ]; }; then set -- node "$@" fi exec "$@" |
行末のexec “$@”を紐解きます。
execコマンドは、現在のプロセスを指定されたプログラムに置き換えます。”$@”は、全てのコマンドラインの引数です。つまり、シェルスクリプト内で実行されたコマンドライン引数を、現在のプロセスに置き換えて実行するための構文です。
“$@”で指定されるものは
もう一度、node:18イメージのソースコードを確認しましょう。
1 2 |
ENTRYPOINT ["docker-entrypoint.sh"] CMD ["node"] |
CMD命令とはなんでしょうか。CMD命令とは、Dockerコンテナが実行されたときに実行されるコマンドを定義するために使用されます。詳細は割愛しますが、上のソースコードの場合docker-entrypoint.shnodeが実行されます。
つまり、コマンドライン引数に”node”が指定され、execコマンドで現在のプロセスをnodeコマンドに置き換えて実行します。
nodeコマンドとは
nodeコマンドは、REPL(Read-Eval-Print Loop)環境を提供します。つまり、nodeコマンドのプロセスは自動で停止しません。
ここでもう一つの疑問が解決しました。「プロセスが起動し続けている理由」の回答は、nodeコマンドのプロセスが起動しているからでした。
最後に
OSSのソースコードを読み解くことは勉強になりますね。
次回はなぜ、MLエンジニアを目指しているのかお話しします。
最後までお読みいただきありがとうございました。