• 作成:
  • 更新:

RustのCargoプロジェクトで素直に書いたDockerfileをdocker buildするとソースが書き換わるたびにフルビルドが走って滅茶苦茶遅いことはcargoのファイルだけコピーしてビルドすることで解決します

Docker初心者です.

C++アプリケーションに依存してたりして少し複雑なcargoプロジェクトをDockerで動かせるようにしていました.

素直に

COPY . .
RUN cargo build --release

と書いていたら,ソースに変更を加えるたびに,依存ライブラリのビルドが全て走って,毎回滅茶苦茶時間がかかります.

その対策として,

# プログラムの依存関係だけをコピー
COPY Cargo.toml Cargo.lock /work-dir/
# 何もプログラムが無いとビルドエラーになるのでダミーのものを用意する
RUN mkdir -p /work-dir/src/ && touch /work-dir/src/lib.rs

# キャッシュのために依存ライブラリだけをビルドする
RUN cargo build --release

# リポジトリ全体をコピー
COPY . .

# 本物のビルドを行う
RUN cargo build --release

のようにCargo関連のファイルだけをコピーしてダミーのソースコードを配置してビルドすることで解決します.

参考

stack buildみたいにcargo--only-dependenciesがあれば,ダミーのプログラムなんてtouchしなくて良いのですが,今の所用意されていないようです.

cargo build --dependencies-only · Issue #2644 · rust-lang/cargo

この方法を使っても,自分のアプリケーションは差分ビルドすることは出来ません.

またライブラリのバージョンを1つだけ上げるような行為を行っても当然フルビルドになってしまいます.

ボリュームマウントしたり,コピーを行えば出来るでしょうが,そうするとDockerの意味である環境非依存性がなくなってしまうので,Dockerを使う意義がなくなってしまうのではと思っています.

この辺どうにかならないと開発環境にDocker使う気には絶対ならないですね.本番と同じステージング環境を用意するのには使えるかもしれませんが.