Skip to Content

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でパッケージのバージョンをどう管理するのか考えたことがなかった。
しかし、探したい情報にたどり着けないとは思っていなかった。もっと根本的の部分を知らないだけなのかもしれない。

参考