TL;DR
ビルドキャッシュを効率よく使い、特に Docker コンテナのビルド時間を短くする Cargo の拡張ツール。
なぜ必要か
Docker のキャッシュは、Cargo.toml が複数あるワークスペースでは効かせにくい。cargo-chef はこの場面で特に効果を発揮する。
仕組み
依存するクレートの情報を recipe.json という JSON ファイルに書き出し、それを使ってビルドする。recipe.json はキャッシュの鍵のような役割を持つ。このファイルが変わらなければ、依存のビルドはキャッシュされた状態のまま docker build を実行できる。
README によると、cargo chef prepare でプロジェクトを解析して recipe.json を作り、cargo chef cook で recipe.json から依存をビルドする。recipe.json には、すべての Cargo.toml とその相対パス、Cargo.lock が入る。ワークスペースのクレートは後から増えたものも含めて自動で拾われる。
例
README の Dockerfile は、マルチステージビルドで次の順に進む。planner のステージでソースコードをコピーし、recipe.json を作る。
RUN cargo chef prepare --recipe-path recipe.jsonbuilder のステージでは recipe.json だけをコピーして依存をビルドし、その後でソースコードをコピーしてアプリをビルドする。
RUN cargo chef cook --release --recipe-path recipe.json
RUN cargo build --release --bin app最後のステージでは、ビルドしたバイナリだけを小さなイメージにコピーする。依存が変わらなければ cook のレイヤはキャッシュされたままになる。
注意点
README によると、cargo-chef はローカルで実行するためのものではない。すべてのステージで同じバージョンの Rust を使わないと、キャッシュが効かない。また、キャッシュされたファイルに絶対パスが含まれるので、cargo chef cook と cargo build は同じディレクトリで実行する必要がある。