ダイエットしようぜ!
問題文
問題文は以下の通りでした。
GoでSHA256する
hash.go
を書いた。これを実行するコンテナが欲しかったので雑にDockerfileを書いてビルドしてイメージを作成した。問題なくSHA256できるようになったが、イメージが大きくてテンションが上がらない。 あなたには、Dockerfile
を編集したりビルドコマンドを変えたり、あるいはビルド後のイメージに対してなにかしたりしてイメージを小さくしてほしい。 ただし、hash.go
のコードにはこだわっているので編集してはならない。$ make build
でictsc-dit
という名前のDocker imageを作ることができる。詳細はMakefile
を参照されたい。採点の際にVMを確認する場合、どのイメージが回答によって作成されたイメージかすぐに判別できるよう、是非使ってほしい。
初期状態とゴール
初期状態
$ docker images
で当該イメージを見ると796MBである。- Dockerのコマンドはsudoなしで実行できる。
前提条件
hash.go
を編集してはならない。- もしよければ
$ make build
でDocker imageを作って欲しい。(任意)
終了状態
$ docker images
で当該イメージを見ると796MBより小さくなっている- 可能な限り小さくしてほしい
解説
解法はいくつかあります。
- ベースイメージをalpineベースのものに変える
- docker-slimを使う
- マルチステージビルドを使う
それぞれの解放での結果は以下の通りです。
REPOSITORY TAG IMAGE ID CREATED SIZE
ictsc-dit latest 58e9a0e9f7f8 3 minutes ago 796MB
ictsc-dit-alpine latest 2a94c4a68acb 3 minutes ago 312MB
ictsc-dit.slim latest 756e1ad95108 49 seconds ago 57.9MB
ictsc-dit-msb latest cc7106b528b2 3 minutes ago 8.14MB
マルチステージビルドの解説
まず以下のようにDockerfileを書き直します。
FROM golang:1.11
WORKDIR /work
COPY ./hash.go /work
RUN go build -o app hash.go
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /work/app .
CMD ["./app"]
最初の4行でビルドし、次の5行でビルドした実行ファイルのみalpineにcopyするスタイルです。
その後buildします。
$ docker build -t '${INAME}' .
runすれば動きます。
$ docker run -it --rm --name ${CNAME} ${INAME}
data: abc
SHA256: ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
解説は以上です。
採点基準
()内は任意だが、想定される解法。
- (ベースイメージをAlpineにして)サイズを400MB以下にした: 40%
- (Docker-slimを使って)サイズを100MB以下にした: 70%
- (Multi Stage Buildを使って)サイズを10MB以下にした: 100%
解答について
- 今回の解説では実行をalpineで行なっていますが、当然
FROM scratch
での回答も多かったです。- それはそう。
go build -ldflags '-s -w'
することで実行ファイルを小さくするという工夫を凝らす回答がありました。- デバッグ情報等も削る対象と見るストイックなダイエットに感動しました。
- 実行ファイルをUPXで圧縮し、さらに小さくするという工夫を凝らす回答がありました。
- UPXを知らなかったので学びになりました。
- マルチステージビルドを手動で行なっている回答がありました。
- 最も楽にダイエットに成功していると感じました。
終わりに
1 MBを切るイメージを回答がいくつかありました。
正直ここまでストイックな減量に挑戦してくれるとは思っていなかったので感動しました。
小さなイメージは開発者のテンションを上げることができます。(知らんけど。)
今後もより小さなイメージを目指して頑張ってください。