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関連のファイルだけをコピーしてダミーのソースコードを配置してビルドすることで解決します.
参考
Rust に限らずよくやるやつ。
— 藻 (@bromne) 2019年1月19日
最初に依存関係を記述したファイルだけコピーしてなんとか依存関係のインストールを行なうw(Rust なら Cargo.toml, npm なら package.json)
Answer: Optimising cargo build times in Docker https://t.co/nnnhdPk6Tf
stack build
みたいにcargo
に--only-dependencies
があれば,
ダミーのプログラムなんてtouch
しなくて良いのですが,
今の所用意されていないようです.
cargo build --dependencies-only · Issue #2644 · rust-lang/cargo
この方法を使っても, 自分のアプリケーションは差分ビルドすることは出来ません.
またライブラリのバージョンを1つだけ上げるような行為を行っても当然フルビルドになってしまいます.
ボリュームマウントしたり, コピーを行えば出来るでしょうが, そうするとDockerの意味である環境非依存性がなくなってしまうので, Dockerを使う意義がなくなってしまうのではと思っています.
この辺どうにかならないと開発環境にDocker使う気には絶対ならないですね. 本番と同じステージング環境を用意するのには使えるかもしれませんが.