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(実験的機能)」のままだった.参考に載せておく!