この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
apt-getの呪文
Dockerfile内でapt-getを使ってアプリケーションをインストーするするとき以下のようなものをよく見ると思います。
apt-getの呪文
RUN apt-get update && apt-get install -y \
xxx \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
公式ドキュメントによればこれらはDockerのイメージサイズを小さくする効果があるようです。 今回はこれを紐解いて行こうと思います。
比較
疑問が多いのは以下の部分だと思います。
apt-get clean
rm -rf /var/lib/apt/lists/*
これらをそれぞれない状態にしてイメージサイズを比較してみます。 今回はUbuntu:22.04をもとにNginxをインストールします。
イメージサイズ | |
---|---|
全部あり | 136.72MB |
apt-get cleanだけ実行 | 176.54MB |
rm -rf /var/lib/apt/lists/*だけ実行 | 136.72MB |
両方なし | 176.54MB |
確かに、全部ありはイメージサイズが小さいです。
rm -rf /var/lib/apt/lists/*
も同じ値になっています。
apt-get clean
だけを行ったものは両方ない場合と同じになっています。
それぞれのコマンドの意味を見ていきます。
apt-get clean
apt-get clean
はaptがダウンロードしてきたDebianパッケージファイルを削除するためのコマンドです。
ダウンロードされてきたファイルは/var/cache/apt
以下に一時的に保存され、再度インストールする際はダウンロードせずこちらが使用されます。
ではなぜこのコマンドはイメージサイズに影響を与えなかったのでしょうか?
この秘密は/etc/apt/apt.conf.d/docker-clean
にあります。
ここにはaptの設定が書いてあり、内容は以下のとおりです。
docker-clean
DPkg::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };
APT::Update::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };
Dir::Cache::pkgcache "";
Dir::Cache::srcpkgcache "";
ここでaptの設定を行っており、インストール後に自動的にapt-get clean
相当の処理が走るようになっています。
つまりは、RUN命令に含めなくとも自動でダウンロードしたパッケージを削除してくれるということです。
UbuntuやDebianの公式イメージではこの設定がすでに行われています。
Dockerfile
FROM ubuntu:22.04
RUN rm /etc/apt/apt.conf.d/docker-clean
RUN apt-get update && apt-get install -y \
nginx
実際上記のようなDockerfileを作成しイメージをビルドするとイメージサイズは275.04MBととなります。
キャッシュの確認
/# ls -la /var/cache/apt/archives | head
total 17224
drwxr-xr-x. 1 root root 4096 Dec 1 07:59 .
drwxr-xr-x. 1 root root 65 Dec 1 07:59 ..
-rw-r--r--. 1 root root 29096 Mar 24 2022 fontconfig-config_2.13.1-4.2ubuntu5_all.deb
-rw-r--r--. 1 root root 1041300 Feb 22 2021 fonts-dejavu-core_2.37-2build1_all.deb
-rw-r--r--. 1 root root 1070038 Mar 24 2022 iproute2_5.15.0-1ubuntu2_amd64.deb
-rw-r--r--. 1 root root 22768 Mar 25 2022 libatm1_1%3a2.5.1-4build2_amd64.deb
-rw-r--r--. 1 root root 139806 Jan 25 2022 libbpf0_1%3a0.5.0-1_amd64.deb
-rw-r--r--. 1 root root 315164 Mar 24 2022 libbrotli1_1.0.9-2build6_amd64.deb
-rw-r--r--. 1 root root 44760 Jan 25 2022 libbsd0_0.11.5-1_amd64.deb
実際/var/cache/apt/
以下に.deb
ファイルが残されています。
では、このapt-get clean
は不要でしょうか?
それは使用するイメージによります。
ダウンロードしたパッケージの自動クリーンが入っていないイメージを使用する場合はあったほうが良いでしょう。
rm -rf /var/lib/apt/lists/*
/var/lib/apt/lists
以下を削除していますがここには何が入っているのでしょうか?
ここにはapt-get update
で取得したリポジトリのパッケージのリストが保存されています。
パッケージのリスト
/# du -sh /var/lib/apt/lists
39M /var/lib/apt/lists
# ls -al /var/lib/apt/lists/ | head
total 39024
drwxr-xr-x. 1 root root 4096 Dec 1 07:58 .
drwxr-xr-x. 1 root root 42 Dec 1 07:59 ..
-rw-r--r--. 1 root root 99847 Dec 1 07:02 archive.ubuntu.com_ubuntu_dists_jammy-backports_InRelease
-rw-r--r--. 1 root root 4893 Aug 24 19:11 archive.ubuntu.com_ubuntu_dists_jammy-backports_main_binary-amd64_Packages.lz4
-rw-r--r--. 1 root root 11115 Nov 30 16:18 archive.ubuntu.com_ubuntu_dists_jammy-backports_universe_binary-amd64_Packages.lz4
-rw-r--r--. 1 root root 114016 Dec 1 07:02 archive.ubuntu.com_ubuntu_dists_jammy-updates_InRelease
-rw-r--r--. 1 root root 1566039 Dec 1 02:50 archive.ubuntu.com_ubuntu_dists_jammy-updates_main_binary-amd64_Packages.lz4
-rw-r--r--. 1 root root 12559 Nov 18 01:25 archive.ubuntu.com_ubuntu_dists_jammy-updates_multiverse_binary-amd64_Packages.lz4
-rw-r--r--. 1 root root 1024871 Dec 1 01:17 archive.ubuntu.com_ubuntu_dists_jammy-updates_restricted_binary-amd64_Packages.lz4
このディレクトリだけで39MBもあるので削除しておいたほうが無難でしょう。
問題としてはDockerfilen内で複数回apt-update
を走らせるたびに毎回取得が入ってしまいます。
ですが、よほど高速にビルドしたいという局面以外は毎回削除することが安全だと思っています。
最後に
Dockerにおけるapt-getの利用方法としてよく練られたコマンドだと思いました。
DebianやUbuntuの公式イメージは自動でapt-get clean
してくれるのでありがたいですね。
付録
以下に今回使用したDockerファイルを載せておきます。
両方あり
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y \
nginx \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
apt-get clean だけ
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y \
nginx \
&& apt-get clean
rm -rf /var/lib/apt/lists/*だけ
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y \
nginx \
&& rm -rf /var/lib/apt/lists/*
両方なし
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y \
nginx