1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

cargo chefでDockerにおけるRustビルド時間を短縮する方法、Workspaceの工夫する点

1
Last updated at Posted at 2026-09-09

はいさい〜

概要

cargo-chefを使ってDockerでビルドしているRustアプリのビルド時間を短縮する方法を紹介します。

問題

Dockerのキャッシュの仕組みとRustのビルドの相性が合わず、対策をしないと、毎回第三者パッケージをゼロからコンパイルし直すことになる

これでCICDのパイプラインが遅くなるばかりか、GitHub Actionsなど稼働時間によって課金されるサービスを使っている場合は料金に直結する問題です。💰💰

解決法

筆者が今回自らのプロジェクトで試した手法は、本題のcargo chefを使うことでした。

以下、元のファイルです:

FROM rust:1.98.0 AS builder
WORKDIR /app

RUN apt-get update && apt-get install -y cmake libopenblas-dev libomp-dev git libgtest-dev build-essential wget unzip libgflags-dev

RUN git clone https://github.com/facebookresearch/faiss.git .
RUN git checkout 20f14b31a6d54e243a3d1de6ae193fc4c3ec18ed

# Faiss build
RUN cmake -B build -DFAISS_ENABLE_GPU=OFF -DFAISS_ENABLE_C_API=ON -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release -DFAISS_ENABLE_PYTHON=OFF -DBUILD_TESTING=OFF
RUN cmake --build build
RUN make -C build -j8 faiss_c
RUN make -C build install
RUN cp /app/build/c_api/libfaiss_c.so /usr/lib/

# Download libtorch
RUN wget -O /tmp/libtorch-240.zip https://download.pytorch.org/libtorch/cpu/libtorch-shared-with-deps-2.11.0%2Bcpu.zip
RUN unzip /tmp/libtorch-240.zip -d /tmp/
RUN cp -r /tmp/libtorch /usr/lib/
RUN cp -a /tmp/libtorch/lib/** /usr/lib/

ENV LIBTORCH_INCLUDE=/usr/lib/libtorch
ENV LIBTORCH_LIB =/usr/lib/libtorch
ENV LIBTORCH=/usr/lib/libtorch
ENV LD_LIBRARY_PATH=${LIBTORCH}/lib:$LD_LIBRARY_PATH

COPY lb_jh_servers/Cargo.toml .
COPY Cargo.lock .

COPY . .

RUN cargo build -p lb_jh_servers --bin admin --release --features admin_app

FROM debian:stable-slim AS runner

# 省略

コンパイルするアプリは、Faissだったり、LibTorchだったり、機械学習とAI関連の複雑な部品を使ったビルドでRustの依存パッケージのビルドも非常に時間のかかるものです。

そして、cargo-chefを使って書き直したら以下のようになりました:

FROM rust:1.97.1 AS chef
RUN cargo install --locked cargo-chef
WORKDIR app

FROM chef AS planner
WORKDIR /app

COPY . .

RUN cargo chef prepare --bin admin --recipe-path recipe.json

FROM chef AS builder
WORKDIR /app

RUN apt-get update && apt-get install -y cmake libopenblas-dev libomp-dev git libgtest-dev build-essential wget unzip libgflags-dev

RUN git clone https://github.com/facebookresearch/faiss.git .
RUN git checkout 20f14b31a6d54e243a3d1de6ae193fc4c3ec18ed

# Faiss build
RUN cmake -B build -DFAISS_ENABLE_GPU=OFF -DFAISS_ENABLE_C_API=ON -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release -DFAISS_ENABLE_PYTHON=OFF -DBUILD_TESTING=OFF
RUN cmake --build build
RUN make -C build -j8 faiss_c
RUN make -C build install
RUN cp /app/build/c_api/libfaiss_c.so /usr/lib/

# Download libtorch (x86)
RUN wget -O /tmp/libtorch-240.zip https://download.pytorch.org/libtorch/cpu/libtorch-shared-with-deps-2.11.0%2Bcpu.zip
RUN unzip /tmp/libtorch-240.zip -d /tmp/
RUN cp -r /tmp/libtorch /usr/lib/
RUN cp -a /tmp/libtorch/lib/** /usr/lib/

ENV LIBTORCH_INCLUDE=/usr/lib/libtorch
ENV LIBTORCH_LIB =/usr/lib/libtorch
ENV LIBTORCH=/usr/lib/libtorch
ENV LD_LIBRARY_PATH=${LIBTORCH}/lib:$LD_LIBRARY_PATH

# Use rust build dep cache
COPY --from=planner /app/recipe.json recipe.json
RUN cargo chef cook --release --bin admin --recipe-path recipe.json --features admin_app

COPY . .

RUN cargo build -p lb_jh_servers --bin admin --release --features admin_app

ここでcargo-chefのおかげで、planner段階から取得されたrecipe.jsonで含まれた依存パッケージが変わっていなければ、Dockerのキャッシュが利用され、多くの第三者依存パッケージを再ビルドせずに、スキップできるようになるのです。

Workspaceでの注意点

筆者の場合、複数のパッケージが同じRust Workspaceに置かれており、指定しないと不要なパッケージまでビルドされてしまうし、実際にcargo buildを実行する時にcargoのキャッシュが外れます。

この場合は、cargo-chefの--binフラグを使います。

使っているRust Workspaceのビルド対象になるbinの名前を調べて、cargo chef prepare --bin my_bin、cargo chef cook --bin my_binというふうに両方のコマンドで実行すると、そのbinに必要なパッケージのみがrecipe.jsonに含まれます。
ちなみに、対象にしたいbinのworkspaceにおける名前がわからない場合はcargo build --binを実行すれば、すべてのbin名を教えてくれます。

その他の注意点

筆者が困ったところの注意点を共有して参考になればと思います。

--releaseフラグ

cargo-chefのcookコマンドで--releaseのフラグを使用しないで、実際にcargo buildのところで--releaseを使ってしまうと、せっかくコンパイルされた第三者依存パッケージが無駄になってしまうので、忘れないようにお気をつけください。

--featuresフラグ

これもcargo-chefのcookコマンドですが、cargo build --features ...で指定しているものも、同様にcargo chef cook --features ...のところで指定しないとまたキャッシュが外れてしまいます。

RUNの順番

Dockerのキャッシュの仕組みを深く説明するつもりはないのですが、ステップ間で変更を検知すれば、キャッシュを無視して再実行になるので、cargo-chefのコマンドを実行する場所と、Rustのコンパイルに必要なファイルのコピー(COPY . .)のステップにご注意ください。
RUN cargo chef cook ...は必ずCOPY . .の前にします。そうじゃないとキャッシュは無意味になります。

まとめ

こちらの場合は、30分〜40分かかっていたビルドが、今回の改善で10~11分台に短縮できたので大いに満足しています。待ち時間が長すぎていよいよイライラが行動を起こしたのです。
皆さんも同様な問題を抱えているなら、ぜひ解決しましょう。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?