ダイエットしようぜ!

問題文

問題文は以下の通りでした。

GoでSHA256するhash.goを書いた。これを実行するコンテナが欲しかったので雑にDockerfileを書いてビルドしてイメージを作成した。問題なくSHA256できるようになったが、イメージが大きくてテンションが上がらない。 あなたには、Dockerfileを編集したりビルドコマンドを変えたり、あるいはビルド後のイメージに対してなにかしたりしてイメージを小さくしてほしい。 ただし、hash.goのコードにはこだわっているので編集してはならない。 $ make buildictsc-ditという名前のDocker imageを作ることができる。詳細はMakefileを参照されたい。採点の際にVMを確認する場合、どのイメージが回答によって作成されたイメージかすぐに判別できるよう、是非使ってほしい。

初期状態とゴール

初期状態

  • $ docker imagesで当該イメージを見ると796MBである。
  • Dockerのコマンドはsudoなしで実行できる。

前提条件

  • hash.goを編集してはならない。
  • もしよければ$ make buildでDocker imageを作って欲しい。(任意)

終了状態

  • $ docker imagesで当該イメージを見ると796MBより小さくなっている
    • 可能な限り小さくしてほしい

解説

解法はいくつかあります。

  1. ベースイメージをalpineベースのものに変える
  2. docker-slimを使う
  3. マルチステージビルドを使う

それぞれの解放での結果は以下の通りです。

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を切るイメージを回答がいくつかありました。
正直ここまでストイックな減量に挑戦してくれるとは思っていなかったので感動しました。
小さなイメージは開発者のテンションを上げることができます。(知らんけど。)
今後もより小さなイメージを目指して頑張ってください。