如何在 docker 中緩存加速 Rust 依賴構建
文章目錄
-
本地緩存 - 失敗
-
鏡像緩存 - 成功
最近開始學習 《陳天 · Rust 編程第一課》,在用docker
鏡像打包構建代碼示例時,每次都會在更新crate.io
索引上等上一會,即便在沒有修改Cargo.tomal
依賴的前提下。
想着難道沒有辦法緩存下更新麼,於是就有了這篇新手踩坑指南。
本地緩存 - 失敗
查閱有在docker
中指定CARGO_HOME
到宿主機來緩存crate.io
索引
命令如下:
docker run --rm --user "$(id -u)":"$(id -g)" -v "$PWD":/usr/src/myapp -w /usr/src/myapp -e CARGO_HOME=".cargo" rust cargo run
然而結果,鏡像 run 失敗了
Compiling libc v0.2.107
Compiling autocfg v1.0.1
Compiling siphasher v0.3.7
Compiling unicode-xid v0.2.2
Compiling memchr v2.4.1
Compiling lazy_static v1.4.0
Compiling ppv-lite86 v0.2.15
Compiling pin-project-lite v0.2.7
Compiling pkg-config v0.3.22
error: failed to build archive: Input/output error
error: error writing dependencies to `/usr/src/myapp/.target/debug/deps/pkg_config-8dafe7024c916ac6.d`: Input/output error (os error 5)
一番查閱,應該是環境不一致時pkg-config
編譯時鏈接庫有問題,詳見 Rust 交叉編譯 OSX 二進制失敗原因分析 [1] 和 Unable to run a Docker image with a Rust executable[2]
鏡像緩存 - 成功
然後就搜到了這篇 cache-rust-dependencies-with-docker-build[3]
真是非常 tricky!
思想很簡單,就是緩存要在依賴不變的前提下,而 docker build 時源代碼更改會使緩存的docker layer
失效。
那就先用一個不會變的源代碼編譯依賴,編譯好了依賴緩存 layer,再文件替換到實際代碼,重新進行編譯就正常運行加緩存兩不誤了。
具體構建方式如下:
FROM rust
WORKDIR /app
RUN echo "fn main() {}" > dummy.rs
ARG SRC_DIR
ENV SRC_DIR=${SRC_DIR:-}
COPY ${SRC_DIR}/Cargo.toml .
RUN sed -i 's#src/main.rs#dummy.rs#' Cargo.toml
RUN cargo build --release
RUN sed -i 's#dummy.rs#src/main.rs#' Cargo.toml
COPY ${SRC_DIR}/. .
RUN cargo build --release
ENTRYPOINT ["target/release/app"]
這裏構建參數
SRC_DIR
是爲了指定不同代碼,複用同一個Dockerfile
相應的Cargo.toml
指定打包的程序名和路徑
[[bin]]
name = "app"
path = "src/main.rs"
打包和運行則可以一行命令搞定:
# run.sh
#!/usr/bin/env bash
WORKSPACE=$(cd "$(dirname "$0")" && pwd -P)
docker run --rm -it "$(docker build --build-arg SRC_DIR="$SRC_DIR" -q "$WORKSPACE" -t "rust-$SRC_DIR")" #"$@"
運行時:
# eg:
# SRC_DIR=scrape_url sh run.sh https://www.rust-lang.org/ rust.md
完美緩存了依賴更新,可以繼續學習了
本文代碼示例詳見 rust-koan[4]
參考資料
[1]
Rust 交叉編譯 OSX 二進制失敗原因分析: https://ttys3.dev/post/rust-cross-compile-darwin-target-troubleshooting/
[2]
Unable to run a Docker image with a Rust executable: https://stackoverflow.com/a/49173699/4431337
[3]
cache-rust-dependencies-with-docker-build: https://stackoverflow.com/a/58474618/4431337
[4]
rust-koan: https://github.com/NewbMiao/rust-koan
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/Sh2-92U4fKS4PUMFCZyMug