Dockerのimageを作るときにAlpineを使ってイメージサイズを小さくしてるよ!
なんて記事をたくさん見かけますが、チャンチャラおかしいですね。
まず下の実行結果を見てください。
ubuntu@instance-1:~$ docker run -t --rm hello:alpine /hello
hello, world
ubuntu@instance-1:~$ docker run -t --rm hello:scratch /hello
hello, world
hello:alpine、hello:scratch ともに/helloが同じように動いてますね?
名前から分かる通りhello:alpineはAlpineをベースにして作成したイメージです。
では、Imageのサイズを比較してみましょう。
ubuntu@instance-1:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello scratch 0b6f9da6ef84 10 hours ago 3.12MB
hello alpine b8765dbaee21 3 minutes ago 7.08MB
hello:alpineのサイズは 倍以上 ですよ先生。
Alpineは 重い ですねぇ...
さて、じゃあhello:scratchはどう作っているのか。
の前にhello:alpineの作り方を見てみましょう。
FROM alpine:latest
MAINTAINER Yuuichi Fujioka
ADD hello hello
CMD ["/hello"]
普通に Alpineのイメージにhelloを追加しているだけですね。よく見るやつです。
次にhello:scratchの作り方です。
FROM scratch
MAINTAINER Yuuichi Fujioka
ADD hello hello
CMD ["/hello"]
hello:alpineとの差はベースイメージのみで、こちらはscratch を元にして作っているのです。
scratchには何も入っていないので、単純にhelloの分しか容量を食わないのです。
なぜhelloしか入っていないイメージが動くのか?
それは実に単純な話で、helloがただの一つも外部ライブラリに依存していない、このファイル単一で実行可能なファイルだからなのです。
ubuntu@instance-1:~$ ldd hello
not a dynamic executable
わかりましたか?Alpineなんてなくても動くイメージは作れるのです。
あなたはまだAlpineを使ってるんですか?
備考1:
このイメージの作り方だと起動中のコンテナの中でデバッグ等はできません。だってshも入ってないんですもの。
コンテナの中に入ってなんやかんやしたければAlpineなり何なりを使えば良いです。
備考2:
scratchイメージの詳しい説明はdocker storeのscratchのページやdocker-libratyのリポジトリにあります。
備考3:
どうでもいいですが、今回使ったhelloはGo言語で作ったものです。
https://github.com/yuuichi-fujioka/hello-world
シングルバイナリで動的ライブラリを使わない実行形式のファイルが簡単にできていいですね、Go。