はてな記事執筆機能の素振りがてら書いてみる。
序論
最近Dockerfileをビルドする際に複数のBuild contextを指定できるようになったらしい。
これを使うと、例えば共通モジュールが別ディレクトリに切り出されているような場合に、よりきれいにビルドコンテキストを渡すことができる。 以下に簡単な例とともに紹介する。
従来の問題
例えばこんなディレクトリ構成の場合:
. ├── app1 │ ├── Dockerfile │ └── index.py ├── app2 │ ├── Dockerfile │ └── index.py └── common └── util.py
従来だと app1
をビルドする際に common
ディレクトリもBuild contextに含めたい場合、ルートディレクトリをBuild contextに含める必要があった。
# ビルド実行
docker build .
これだとDockerfile内でファイルを参照する際もルートディレクトリからの相対パスとなり、美しくない。また、Build contextに関係のないディレクトリ (app2
) が含まれるのも(実害はなさそうだが)気になる。
FROM python:3.9.12-buster COPY app1/index.py ./ COPY common/util.py ./ CMD ["python3", "index.py"]
この課題感はこちらのIssueでも議論されていた。 How to include files outside of Docker's build context? - Stack Overflow
新しいMulti build context機能
一方、新しいMulti build context機能を使うと、以下のように書ける。
# syntax=docker/dockerfile:1.4 FROM python:3.9.12-buster # app1からの相対パスで解決 COPY index.py ./ # commonディレクトリは別のBuild contextから読み込み COPY --from=common util.py ./ CMD ["python3", "index.py"]
# ビルド実行 cd app1 docker buildx build . --build-context common=../common
このように、buildx build
コマンドの --build-context
オプションにより、任意の数のBuild contextを名前付きで追加できる。これらのBuild contextは、上の例のように COPY --from
などで指定可能 (Multi-stage buildで使う記法に似ている。)
これにより、単一Build contextしか渡せなかった従来の問題が解決されている。
その他
今のところ --build-context
オプションは buildx build
コマンドでのみ利用でき、 docker build
コマンドでは利用できない。
docker buildx build | Docker Documentation
docker build | Docker Documentation
このため、既存ツールと連携したい場合は工夫が必要/不可能かもしれない。
自分は最近Docker buildをもっぱらAWS CDKから呼び出しているので、CDKが対応しない限りは使えなさそう。いずれはそういったところも対応してくれたらなーと思う。