ずん
「Dockerのビルドが遅すぎて、ボクの昼寝時間が削られるのだ!これは労働搾取なのだ!」
でぇじょうぶ博士
「それは単におめぇの怠惰でやんす。でも確かに、Dockerビルドの最適化は現代エンジニアの必修科目でやんすね。」
やきう
「ワイのプロジェクト、ビルドに10分かかるんやが。コーヒー淹れて戻ってきても終わらんのや。」
でぇじょうぶ博士
「10分...?おいらのプロジェクトは30秒でやんす。BuildContextの見直しから始めるといいでやんすよ。」
ずん
「BuildContext?なにそれ美味しいのだ?」
でぇじょうぶ博士
「BuildContextはビルド時にDockerデーモンに送られるファイル群でやんす。.gitとか無駄なものを.dockerignoreで除外すれば、転送量が激減するでやんす。」
やきう
「なるほどな。でもワイ、COPY . .って書いてるわ。」
でぇじょうぶ博士
「それは全部コピーしてるでやんす!必要なファイルだけ指定するのが基本でやんすよ。BuildKitが賢く除外してくれるとはいえ、限界があるでやんす。」
ずん
「じゃあ、全部消せばいいのだ!ファイルゼロで最速なのだ!」
でぇじょうぶ博士
「それじゃ何もビルドできないでやんす...。diveツールでイメージの中身を可視化して、無駄を見つけるのが賢いやり方でやんすよ。」
やきう
「レイヤーキャッシュってのも気になるんやが、あれ何回やっても効かへんねん。」
でぇじょうぶ博士
「それは命令の順序が悪いでやんす。変更の少ない処理を前に、変更の多い処理を後ろに配置するのが鉄則でやんす。Goならモジュールダウンロードを先に切り出すだけで劇的に改善するでやんすよ。」
ずん
「なるほど!じゃあボクは変更しないから、全部キャッシュが効くのだ!」
でぇじょうぶ博士
「変更しなかったら開発にならないでやんす...。それより、Bind mountsやCache mountsを使えば、ビルドに必要なファイルを一時的にマウントできて、レイヤーに残らないでやんす。」
やきう
「Bind mountsか。なんかカッコええな。使ってみるわ。」
でぇじょうぶ博士
「ただし、GitHubActionsではCache mountsを使うために『buildkit-cache-dance』という専用アクションが必要でやんす。ここが罠でやんすね。」
ずん
「buildkit-cache-dance...ダンス踊るのだ?」
でぇじょうぶ博士
「踊らないでやんす。名前がオシャレなだけでやんす。これを使えば、レイヤーキャッシュが効かなくてもビルドキャッシュを再利用できるでやんすよ。」
やきう
「イメージサイズも気になるんやが、どうすればええんや?」
でぇじょうぶ博士
「まず、ベースイメージをdistrolessに変えるでやんす。Googleが提供する超軽量イメージで、alpineより小さくてセキュアでやんす。CGO_ENABLED=0でビルドすれば、distroless/staticに乗せられるでやんすよ。」
ずん
「distroless...ディストロがレスということは、何もないのだ?」
でぇじょうぶ博士
「必要最小限はあるでやんす。無駄がないだけでやんす。おいらみたいに効率的でやんすね。」
でぇじょうぶ博士
「go build時に`-ldflags="-s -w -trimpath"`を指定すれば、デバッグ情報を削除してバイナリが小さくなるでやんす。Go1.22以降は-sだけでOKでやんすよ。」
でぇじょうぶ博士
「それが落とし穴でやんす。レイヤーは既にGzipで圧縮されてるから、UPXで二重圧縮しても効率が悪いでやんす。展開プログラムも余分に入るから、逆効果になることもあるでやんすよ。」
やきう
「マジか。じゃあ圧縮方法変えたらどうなるんや?」
でぇじょうぶ博士
「Gzipをzstdに変えれば、圧縮率が高くて速度も速いでやんす。docker/build-push-actionで`oci-mediatypes=true`と`compression-level=3`を設定すれば、20%もサイズが減るでやんすよ。」
ずん
「20%!?それはすごいのだ!ボクの体脂肪率も20%減らしたいのだ!」
でぇじょうぶ博士
「それは運動するしかないでやんす...。ちなみに、実行環境を強化するのも効果的でやんす。namespace.soというSaaSを使えば、Cache Volumesでキャッシュを物理的にアタッチして、I/O遅延を大幅に削減できるでやんす。」
やきう
「namespace.so...なんかオシャレやな。使ってみるわ。」
でぇじょうぶ博士
「弊プロジェクトではCI実行時間が半分になったでやんす。数字で効果が見えるのがパフォーマンスチューニングの醍醐味でやんすね。」
ずん
「なるほど!じゃあボクは何もしなくてもいいのだ!勝手に速くなるのだ!」
でぇじょうぶ博士
「何もしなかったら何も変わらないでやんす。.dockerignoreを書いて、Dockerfileを見直して、hadolintで静的解析して、diveでイメージを確認して、初めて効果が出るでやんすよ。」
ずん
「じゃあボクは昼寝の時間を削って、ビルド時間を短縮するのだ!...あれ、これ本末転倒なのだ?」