てきとうなさいと べぇたばん

Dockerのイメージのサイズを減らしたかったぼくがしたこと

ディスク容量。かなり減ったなー docker ps -aをするとやたらと多い終了したコンテナがずらりというわけで削除している そして容量が減った。

Docker重いです

困ったことに、歴史を積み上げていけば積み上げていくほどディスクサイズが重くなるのです。コマッタ

何が重いのか

ディスクサイズがおもたすぎます。50%も使っているとか信じられません。すこし鯖を読んで月間5000PVのさいとですから、本当はもっと少ないはずです。そうじゃなきゃおかしい。

ディスク容量を減らす

まず、思い当たる節がイメージを削除することです。

$ sudo docker images -a
$ sudo docker rmi <image>

ちなみに、まとめて削除するならぼくはこうしてます。

$ sudo docker images -a | grep '<none>' | awk '{print $3}' | xargs sudo docker rmi -f

しかし、これでも減りません。うーん。と思ってdocker ps -aコマンドを叩いてみたら、たくさんのExitしているコンテナがありました。

$ sudo docker ps -a

これを削除してしまいましょう。tailコマンドで下から4つのコンテナを削除しています。cutコマンドじゃなくてawkで分けたほうがいいとおもいますがなぜんこんなことしてるんでしょうかね?ぼく。

$ sudo docker ps -a | cut -f1 -d' ' | tail -n4 | xargs sudo docker rm

/var/lib/docker/tmp

duコマンドで/var/lib/docker/を調べた結果、/var/lib/docker/tmpディレクトリがかなり多い事に気がつきました。

$ sudo du -m /var/lib/docker/ | sort -nr | head
5283    /var/lib/docker/
4143    /var/lib/docker/tmp
1742    /var/lib/docker/tmp/docker-builder492918808
1726    /var/lib/docker/tmp/docker-builder492918808/htdocs
1717    /var/lib/docker/tmp/docker-builder739079653
1711    /var/lib/docker/tmp/docker-builder739079653/htdocs
1688    /var/lib/docker/tmp/docker-builder492918808/htdocs/cake
1676    /var/lib/docker/tmp/docker-builder492918808/htdocs/cake/app
1671    /var/lib/docker/tmp/docker-builder739079653/htdocs/cake/app
1671    /var/lib/docker/tmp/docker-builder739079653/htdocs/cake

以下のようにdockerデーモンをstopしたあとで/var/lib/docker/tmpディレクトリを移動させた後、該当のコンテナを起動させれば普通に起動しました。

$ df -lh
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        19G  9.2G  8.7G  52% /
udev             10M     0   10M   0% /dev
tmpfs           201M   25M  176M  13% /run
tmpfs           501M   92K  501M   1% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           501M     0  501M   0% /sys/fs/cgroup
$ sudo service docker stop
$ sudo mv /var/lib/docker/tmp /tmp/docker
$ sudo service docker start

移動させたtmpディレクトリは、削除したら容量がかなりの勢いで減ってしまいました。

$ sudo rm -rf /tmp/docker
$ df -lh
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        19G  5.1G   13G  29% /
udev             10M     0   10M   0% /dev
tmpfs           201M   25M  176M  13% /run
tmpfs           501M   92K  501M   1% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           501M     0  501M   0% /sys/fs/cgroup

なんやねんこれ。こんなんでええのんか〜?

コンテナにPHPバイナリだけ乗っけるのは

これってできるんでしょうかね。と思って調べてみましたが、結局コンパイラを乗っけたほうがいいという結論になりました。

  • phpのconfigureに--hostというクロスコンパイルオプションがあるが、これはあくまでもコンパイル先にコンパイラがあって成立するもののようだ
  • Dockerのshared_directoryを利用してmake installだけやらせようかなと思って試してみたが、考えてみるとmakeするためには結局makeにまつわるツールが必要であんまり変わらない
  • かといって専用のシェルスクリプトかくかぁ?それもやだなぁ。

最適解

Dockerfileではどうするのかと公式をあさったら、どうやらビルド環境を作ったあとにマッサラにしてしまうとか、子どものコンテナを作ってGemfileをああたらこうたらしてとか色々あるようだ。

コンテナにビルド環境を入れたままにしておくのは、ぼくの場合はバージョンアップにすぐに対応できるから。でもまぁ、バージョンアップの時だけ必要な環境をそのまま入れとくのはムダなんだよね。わかるんだけども、利便性には勝てなかったよ…

結局、ぼくの環境での方法が決まってしまっているのならば、それが一番いいでしょうということにする。

コンパイラを乗っける場合に役立つONBUILD

とはいえ、コンパイラをそのままDockerfileに乗っけると、コンパイラを毎回apt-getしてくるということで非効率的なので、コンパイラなどのPHPのバージョンアップに必要のない、おそらく更新することはそれ以上に少ないものに関してはベースイメージにかためてしまいましょう。

$ sudo docker build -t base -f Dockerfile.base .

Dockerfile.baseではどうなっているのかというと、 ONBUILDでPHPのコンパイルを行います。つまり、ベースイメージであるこの状態では実行されません。

ONBUILD RUN ./configure --enable-mbstring ...

この例の場合、DockerfileにFROM baseと書いたものを作っただけで。。。なんとコンパイルができるのです!

$ sudo docker build -t deploy .

ということは、PHPのバージョンアップがあった時にはコンパイルに集中できるということになります。すばらしい。

そして、PHPのビルドするコードはこちらになります。 https://github.com/youkidearitai/make-docker-containar-php7

Dockerコンテナは小さいほうがいい

Dockerのイメージサイズはなるべく小さいほうがいい。とはいいつつ、PHPを使っていることに矛盾があるのだすが、そこは目をつむりましょう。

例えばこれがある程度の規模であるならば、ロードバランサー噛ませて何台かのマシンに分散させるとかになるのかなーと思うのだけど、それってDevOpsでまかなえるんじゃね?とか色々考えることはあります。

Dockerは用法用量を守って、正しくつかいましょう。