2021年7月30日に Docker Blog に公開された以下の記事を参考に「Dockerfile
で新しく使えるようになった構文 "heredocs"」を試す.Dockerfile
で「ヒアドキュメント」を使うと,今まで RUN
と && \
を組み合わせて複数コマンドを 1 レイヤーにまとめていた Tips を使わずにシュッと書けるようになる.なんと!
なお RUN
と && \
を組み合わせる Tips は Intro Guide to Dockerfile Best Practices で「Tip #3: Identify cacheable units such as apt-get update & install」として紹介されていたり,とてもよく知られていると思う.
検証用 Dockerfile
今回は以下のように3種類の検証用 Dockerfile
を作った.あくまで検証として Amazon Linux 2 をベースに yum
コマンドで適当にパッケージをインストールをしている.ヒアドキュメントを使うと 3-heredocs/Dockerfile
のようにシュッと Dockerfile
を書けるようになる.大きく差はなく見えるかもしれないけど,可読性は高くなるし,今まで \
を書き忘れるとエラーになっていたし,とても便利だと思う!
1-base/Dockerfile
: コマンドごとにRUN
を書く2-backslash/Dockerfile
:RUN
と&& \
を組み合わせる3-heredocs/Dockerfile
: ヒアドキュメントを使う
$ tree . . ├── 1-base │ └── Dockerfile ├── 2-backslash │ └── Dockerfile └── 3-heredocs └── Dockerfile 3 directories, 3 files
🐳 1-base/Dockerfile
FROM amazonlinux:2 RUN yum update -y RUN yum install -y git RUN yum install -y tree RUN yum install -y jq RUN yum install -y wget RUN rm -rf /var/cache/yum
🐳 2-backslash/Dockerfile
FROM amazonlinux:2 RUN yum update -y && \ yum install -y git && \ yum install -y tree && \ yum install -y jq && \ yum install -y wget && \ rm -rf /var/cache/yum
🐳 3-heredocs/Dockerfile
# syntax = docker/dockerfile:1.3-labs FROM amazonlinux:2 RUN <<EOF yum update -y yum install -y git yum install -y tree yum install -y jq yum install -y wget rm -rf /var/cache/yum EOF
BuildKit を使ってビルドをする
「ヒアドキュメント」を使った Dockerfile
をビルドするためには BuildKit を使う必要がある.以下のように DOCKER_BUILDKIT=1
環境変数を有効化して docker build
コマンドを実行したり,docker buildx build
コマンドを実行する.またデフォルトで BuildKit を有効化するなら /etc/docker/daemon.json
に設定を追加することもできる.詳しくは以下のサイトに載っている!
$ DOCKER_BUILDKIT=1 docker build . $ docker buildx build .
実際にビルドをすると 2-backslash
と 3-heredocs
は RUN
と && \
を組み合わせなくても同じイメージサイズになっていた.docker history
コマンドの結果も参考までに載せておく.レイヤー数もまとまっている!
$ docker build -t my-image:1-base 1-base/. $ docker build -t my-image:2-backslash 2-backslash/. $ DOCKER_BUILDKIT=1 docker build -t my-image:3-heredocs 3-heredocs/. $ docker images my-image REPOSITORY TAG IMAGE ID CREATED SIZE my-image 1-base 16997f0cd75b About an hour ago 1.62GB my-image 2-backslash de739b8af746 About an hour ago 330MB my-image 3-heredocs c0ec07c5bc12 About an hour ago 330MB $ docker history my-image:2-backslash IMAGE CREATED CREATED BY SIZE COMMENT de739b8af746 About an hour ago /bin/sh -c yum update -y && yum install … 167MB d85ab0980c91 5 days ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B <missing> 5 days ago /bin/sh -c #(nop) ADD file:4cbe5850096b1ae39… 163MB $ docker history my-image:3-heredocs IMAGE CREATED CREATED BY SIZE COMMENT c0ec07c5bc12 About an hour ago RUN /bin/sh -c yum update -y yum install… 167MB buildkit.dockerfile.v0 <missing> 5 days ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B <missing> 5 days ago /bin/sh -c #(nop) ADD file:4cbe5850096b1ae39… 163MB
ヒアドキュメントを活用して Dockerfile
でファイルを作る
Docker Blog の記事を読んでいたら「ヒアドキュメント」を活用して「インラインファイル」を作れると書いてあった.具体的には以下のように nginx に置く index.html
をファイルとして COPY
するのではなく,直接 Dockerfile
に書くことができる.ようするに「ヒアドキュメント」は RUN
だけでなく COPY
にも使える.過剰に使うと読みにくくなるだろうけど,簡単に試す場面なら良さそう.
# syntax = docker/dockerfile:1.3-labs FROM nginx:1.21-alpine COPY <<EOF /usr/share/nginx/html/index.html <html> <body> <h1>kakakakakku blog</h1> </body> </html> EOF
まとめ
Dockerfile
で新しく使えるようになった構文「ヒアドキュメント」を試した.今まで RUN
と && \
を組み合わせて複数コマンドを 1 レイヤーにまとめていた Tips を使わずにシュッと書けて便利💡
関連記事
レイヤーを減らすために docker build
コマンドで --squash
オプションを使うこともできる.2019年に紹介したけど,現在も「Experimental(実験的機能)」のままだった.参考に載せておく!