Rust で書かれたアプリをビルドするための docker image は以下で公開されている。
しかし、ここに出ているように COPY . .
なんてやっていると、 src/main.rs
を触るだけで毎回 cargo install
時に依存するライブラリをすべてダウンロードしてきてコンパイルしてしまい、恐ろしく効率が悪い。
これを避けるには、アプリをビルドする前に依存だけをビルドするレイヤを作っておき、その上に自分のアプリをビルドするレイヤを載せられるといい。しかし、残念なことに、現在の cargo
には依存クレートだけをビルドする仕組みがない。じゃあどうするかというのが、以下のエントリに書かれている。
要点だけ説明すると、まず cargo new --bin my_project
とこれからビルドするプロジェクトと同名のダミーの空のプロジェクトを用意し、そこに Cargo.toml
と Cargo.lock
のみを配置して cargo build --release
する。その後 src/*.rs
を本物に差し替えて、もう一度 cargo build --release
すれば良い。ただし、自分で試してみたところなぜか 2 度目の cargo build
が動いてくれなかったので、 touch src/main.rs
をするなどの処理をおまけで入れておいた。
さて、手元での実行はこれで良いが、 Cloud Build: serverless CI/CD platform | Google Cloud を使うと、前回ビルド済のレイヤを参照できるわけではないのでキャッシュが効いてくれない。 --cache-from
を使う方法もあるが、マルチステージビルドとだいぶ相性が悪い。というのも、ビルドに使ったイメージも破棄せず docker push
しなければならないので。じゃあどうするかというのは、以下のエントリに書かれている。
kaniko
を使えば、 cloudbuild.yaml
は本当に大丈夫かいなってくらい恐ろしくシンプルになる。それでも動かしてみるときちんとキャッシュをする動きになっていて、初回実行が 18M52S
かかる cargo build
が2度目の実行が 1M25S
で済んだ。すばらしい。