docker上でpip installのcache-dirが効くようにする方法を調べてみた
以下の記事の続き。
pythonのバッチ用のイメージを作りたくなったのでサイズがどれくらいになるか調べてみた - podhmo's diary
調べてみたところ、どうやらbuildkitの機能を使うと行けるらしいという事がわかったので色々調べてみた。
python - Using a pip cache directory in docker builds - Stack Overflow
まとめると以下のような状況なので結構嬉しそう。
- pip installのcache-dirが効くようになる
- install時に
--no-cache-dir
を付けていたのと同程度にimage sizeが小さくなる
また以前と同様にpythonのdocker imageをベースに色々調べてみる。 前回と同様にテキトーにbotoやpandasあたりをインストールして試してみる。
cache-dirが効いているかの確認
dockerはbuild時に --no-cache
をつけるとレイヤーのキャッシュを使わずにbuildし直してくれる。
以下の様に2回実行してみたとき、pip installの速度が早くなった。
buildkitの機能を使うには DOCKER_BUILDKIT=1
の環境変数を追加して実行する必要がある。
$ DOCKER_BUILDKIT=1 docker build -t foo:0.1.0 . -f Dockefile.cached --no-cache # --no-cache は dockerの話。 Dockerfile.cachedの.cachedはpipの話。紛らわしい
2回実行してみたときに以下のようにキャッシュが使われていた(出力を一部抜粋)。
#8 4.405 Collecting s3transfer<0.5.0,>=0.4.0 #8 4.408 Using cached s3transfer-0.4.2-py2.py3-none-any.whl (79 kB) #8 4.453 Collecting jmespath<1.0.0,>=0.7.1 #8 4.456 Using cached jmespath-0.10.0-py2.py3-none-any.whl (24 kB) #8 5.512 Collecting botocore<1.21.0,>=1.20.112 #8 5.530 Using cached botocore-1.20.112-py2.py3-none-any.whl (7.7 MB)
このときのDockefileは以下。
Dockerfile.cached
# syntax = docker/dockerfile:experimental FROM python:3.9-slim RUN --mount=type=cache,mode=0755,target=/root/.cache/pip python3 -m pip install boto3 pandas CMD ["python3"]
今回の例では1度目が20s掛かったところが16sになっていた。
1度目
$ DOCKER_BUILDKIT=1 docker build -t foo:0.1.0 . -f Dockerfile.cached --no-cache [+] Building 24.8s (9/9) FINISHED ... => [stage-0 2/2] RUN --mount=type=cache,mode=0755,target=/root/.cache/pip python3 -m pip install boto3 pandas 20.9s ... => => writing image sha256:dcae12aebff6bff55d9a443e5596f6e0b660171c1788eb842743d07ab0feb43b 0.0s => => naming to docker.io/library/foo:0.1.0 0.0s
2度目
$ DOCKER_BUILDKIT=1 docker build -t foo:0.1.0 . -f Dockerfile.cached --no-cache [+] Building 19.4s (9/9) FINISHED ... => [stage-0 2/2] RUN --mount=type=cache,mode=0755,target=/root/.cache/pip python3 -m pip install boto3 pandas 16.6s ... => => writing image sha256:d4a67db6ae9982a8cd55b675c94cfab05dff9fd11a4519a9cd1f837cbd46668b 0.0s => => naming to docker.io/library/foo:0.1.0
image sizeの比較
今度はimage sizeの比較。こちらも前回と同様に調べておきたい。
最もシンプルなfoo:0.0.0
ベースになるDockefileは以下の様なもの。これをfoo:0.0.0とする。これは全くイメージサイズなどを気にせずpip installしただけのイメージ。
Dockefile
FROM python:3.9-slim RUN python3 -m pip install boto3 pandas CMD ["python3"]
$ docker build -t foo:0.0.0
冒頭で試したbuildkitを使った foo:0.1.0
再掲。
Dockefile.cached
# syntax = docker/dockerfile:experimental FROM python:3.9-slim RUN --mount=type=cache,mode=0755,target=/root/.cache/pip python3 -m pip install boto3 pandas CMD ["python3"]
--no-cache-dir
を付けた foo:0.2.0
前回の記事でのimage sizeを気にした比較の時に試した pip install --no-cache-dir
を使ったほうのイメージ。これと同じサイズならいちいちpip install後にファイル削除などする必要がないということになる。
Dockerfile.nocache
# syntax = docker/dockerfile:experimental FROM python:3.9-slim RUN python3 -m pip install --no-cache-dir boto3 pandas CMD ["python3"]
結果
無事foo:0.1.0が --no-cache-dir
をつけて実行したfoo:0.2.0と同じimage sizeとなった。
$ (docker images | ioknife rest | ggrep -P 'foo') |& gsed 's/ */\t/g' REPOSITORY TAG IMAGE ID CREATED SIZE foo 0.2.0 d981b2beccb7 2 minutes ago 293MB foo 0.1.0 7c6ea4f4d154 8 minutes ago 293MB foo 0.0.0 fb6ec39eb3b5 10 minutes ago 329MB
参考
- python - Using a pip cache directory in docker builds - Stack Overflow
- Speed up pip downloads in Docker with BuildKit’s new caching
- BuildKit によるイメージ構築 | Docker ドキュメント