Docker buildのキャッシュについて調べた(一次調査)
疑問
Dockerfile内でRUN apt-get update && apt-get install -y hogehoge
と書いた場合、docker build
のタイミングで都度最新のバージョンに変わるのではないか?だから、パッケージのバージョン名指定でインストールするものだと思っている。
疑問の発端
イラストでわかるDockerとKubernetes
の2章を読んでいた。
キャッシュによるビルドステップの説明で、前回のビルドと得られる結果が異なるステップは実行されるとある。
RUNでインストールしたパッケージはキャッシュを使われており、apt-install
は再実行されない。
- ビルドキャッシュはどこに保存されているのか?
- Dockerfileを別の人、別の端末でビルドしたらインストールされるバージョンは変わる可能性があるのではないか?
調査
Build Cacheの容量を確認できる。
$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 71 2 15.9GB 5.849GB (36%)
Containers 4 0 40.96MB 40.96MB (100%)
Local Volumes 10 6 1.447GB 60.88MB (4%)
Build Cache 20 0 210.6MB 210.6MB
下記リンクからわかったこと。Alpineの例ではあるがパッケージのバージョンを固定したければバージョン指定してインストールというのはその通りだった。しかし、そのバージョンが今後インストールできなくなるとビルドに失敗するリスクがある
docker - How to install a specific package version in Alpine? - Super User
ビルド済みのイメージをDocker Hubからdocker pullする分には良いが、Dockerfileだけの共有だと後々動かせないことは起きうる。
一次調査まとめ
バージョン固定は一概に安全な策とは言えなかった。もちろん脆弱性ある可能性もあるし、最新版使うのが推奨なのはごもっとも。
ビルドキャッシュが、コンテナのイメージレイヤー内なのか、ビルドしたローカル端末にあるのかわからなかった。
ローカル端末にあるのが有力だと思う。CodeBuildなどのCI/CDツール側でコンテナのレイヤーに持っていたらビルドが遅いという話は聞かなさそうである。
おわりに
今までなぜ疑問に思わなかったのかと考えた。マルチステージビルドでGoのビルド済みのバイナリファイルを置いて実行するだけだったから、Dockerfileでパッケージのバージョンをどう管理するのか考えたことがなかった。
しかし、探したい情報にたどり着けないとは思っていなかった。もっと根本的の部分を知らないだけなのかもしれない。