こんにちは。Яeiです。
今回は、現役エンジニアの私がDockerfileのONBUILDの書き方について記事にしようと思います。
ONBUILDはDockerのドキュメントを見てもいまいちピンとこない命令かもしれません。
実際にやってみれば「なるほど」となるので、当記事では実際の挙動を見ながら使い方を解説致します。
当記事は以下の公式リファレンスを元に記載しております。
Dockerfile reference >>
目次
結論:ONBUILDの書き方
書き方は以下となります。
ONBUILD <INSTRUCTION>
INSTRUCTION部分には、このDockerfileで作成したイメージをベースイメージとしたDockerfileで実行したい命令を書きます。
(文字だけだとなんのこっちゃという感じですね)
詳細:ONBUILDの書き方
前提知識(ベースイメージ)
ここではまず前提知識として「ベースイメージ」の考え方について簡単に説明しようと思います。
コンテナを作成する際にはベースとなるイメージを指定します。FROM句で指定するものですね。
基本的にはDockerHubのオフィシャルイメージを指定する場合が多いかと思います。
しかし、セキュリティを意識した場合やイメージサイズを限りなく小さくするために以図のような、
オフィシャルイメージから作成したイメージ
をベースイメージとして利用する縛りを設けることもあります。
ONBUILDはこうした自作イメージをベースイメージとして使っていきたい場合に有効になります。
ONBUILDの使い方
ONBUILD <INSTRUCTION>
INSTRUCTION部分には、このDockerfileで作成したイメージをベースイメージとしたDockerfileで実行したい命令を書きます。
ちなみに、ONBUILDで指定された命令は派生先のイメージビルド時ではFROMの直後に実行されます。
図にすると以下のようなイメージになります(②のDockerfileでは実際にはRUN zzzは記載しません)
このように、①の段階では決めれないけれども、②では必ず実施しないといけない作業があります。
例えばDockerのドキュメントでは以下のような例を挙げられております。
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
これは、srcをコンテナ内に追加して、ビルドをかける処理となります。
srcの内容は①のベースイメージ時点ではわかりませんが、このイメージをベースイメージとして使う際には必ずDockerfileに記載する必要があります。
この必ず実施する作業をONBUILDを使ってベースイメージ側に組み込んでしまおう!ということなのです。
ONBUILDで記載した内容はどのユーザで実行されるのか
ONBUILDで記載した命令はどのユーザで実行されるのか最後に見てみましょう。
結論から申し上げますと、ベースイメージで最後に指定したユーザで実行されることになります。
以下、いくつかお試しで実施してみましたので興味のある方は見ていってください。
・単純にベースイメージでwhoami
FROM nginx:latest
RUN whoami
ONBUILD RUN echo "test"
イメージビルド
docker image build --progress plain . -t test --no-cache
結果、該当部分以外省略
#5 [2/2] RUN whoami
#5 sha256:c5289497f1b3f574427a316bdae66aa2a4d533b09b7de9142346f98e2d57974a
#5 0.356 root
#5 DONE 0.4s
→rootユーザになります。これは当たり前ですね。
・ユーザを切り替えたてベースイメージでwhoami
FROM nginx:latest
RUN adduser rei
USER rei
RUN whoami
ONBUILD RUN echo "test"
イメージビルド
docker image build --progress plain . -t test --no-cache
結果、該当部分以外省略
#6 [3/3] RUN whoami
#6 sha256:29db1c61dae4cdab1542d778eeefe32f1a196f58816c41f34be2024a1e9e6f8b
#6 0.460 rei
#6 DONE 0.5s
→追加したユーザになります。これも当然ですね。
・ベースイメージはrootユーザ設定のままONBUILD
FROM nginx:latest
ONBUILD RUN whoami
ONBUILD RUN echo "test"
FROM test:latest
RUN whoami
RUN echo "test1"
RUN echo "test2"
結果、該当部分以外省略
#4 [2/4] RUN whoami
#4 sha256:9926b66b78b6df0e298117abe59b751a46a5202503c4b58a64837500020d309d
#4 0.291 root
#4 DONE 0.3s
#5 [3/4] RUN echo "test"
#5 sha256:21a548879aa03bd50f24b1523fe29915670a1a09530f35eb69b9075b136cf203
#5 0.432 test
#5 DONE 0.4s
#6 [4/4] RUN whoami
#6 sha256:b15eb75581fae54c7a88bbb417b4dc53391d8f57487d0bf97b98f315ff7339ea
#6 0.507 root
#6 DONE 0.5s
#7 [5/4] RUN echo "test1"
#7 sha256:26528db2975d472e018d9b691aa1914f159b83a7595768c4f349c5c277e6e633
#7 0.524 test1
#7 DONE 0.5s
→rootユーザで実行されます。
・ベースイメージで追加したユーザ設定してONBUILD
FROM nginx:latest
RUN adduser rei
USER rei
ONBUILD RUN whoami
ONBUILD RUN echo "test"
FROM test:latest
RUN whoami
RUN echo "test1"
RUN echo "test2"
結果、該当部分以外省略
#5 [2/4] RUN whoami
#5 sha256:06cf4336a2858c71310e9301ebd0064db830f042f9395bde46b0b5aa22fbfcc9
#5 0.316 rei
#5 DONE 0.3s
#6 [3/4] RUN echo "test"
#6 sha256:924758d8c4712ab00863e933fd0b26cec8d21a89067776760c84878a44b644b2
#6 0.452 test
#6 DONE 0.5s
#7 [4/4] RUN whoami
#7 sha256:533481299ebeadf98576539902055716ffdecddea397d370de9065dea75aadef
#7 0.497 rei
#7 DONE 0.5s
#8 [5/4] RUN echo "test1"
#8 sha256:0e26940b2771b04584426c96f96e84f784ec1a4a10a203507b9755e97101d2bf
#8 0.596 test1
#8 DONE 0.6s
→ベースイメージ側でユーザ切り替えしているため、実行ユーザはベースイメージ側で指定されたユーザでの実行になります。
・ベースイメージでroot指定、派生イメージで追加したユーザ設定
FROM nginx:latest
RUN adduser rei
ONBUILD RUN whoami
ONBUILD RUN echo "test"
FROM test:latest
USER rei
RUN whoami
RUN echo "test1"
RUN echo "test2"
結果、該当部分以外省略
#4 [2/4] RUN whoami
#4 sha256:9926b66b78b6df0e298117abe59b751a46a5202503c4b58a64837500020d309d
#4 0.369 root
#4 DONE 0.4s
#5 [3/4] RUN echo "test"
#5 sha256:21a548879aa03bd50f24b1523fe29915670a1a09530f35eb69b9075b136cf203
#5 0.397 test
#5 DONE 0.4s
#6 [4/4] RUN whoami
#6 sha256:897771abfeb2e1425d27370886f67e4d8a84dae797b469f82adb7a02f06c68de
#6 0.529 rei
#6 DONE 0.5s
#7 [5/4] RUN echo "test1"
#7 sha256:c02349a428727ff17902aa7774749893bc1a2f91e4471d05409caf55341cc274
#7 0.585 test1
#7 DONE 0.6s
→ONBUILDで実行された結果はrootユーザ、RUNで実行した方は指定したユーザで実行される。
当記事は以上となります。
ONBUILD命令は使い方が少し難しい命令になりますが、自分が作成するイメージがベースイメージとなる場合に効果を発揮します。
ONBUILDでどこまで命令しているかを明記したりと、展開方法は少し難しくなりますがうまく使えば利用者側で楽をできるので良いでしょう。
長々とお疲れさまでした。