cargo fetch and cargo vendor with just Cargo.lock
697
cargo-lock-fetch - cargo fetch and vendor with just Cargo.lockThis cargo plugin fetches and optionally vendors crates based
only on Cargo.lock.
It is particularly useful when building rarely changing docker layers containing just project
dependencies without copying/mounting all Cargo.toml files of a multi-crate workspace.
cargo-lock-fetch is mainly intended to be used with containers. Docker users can copy it from the
binary docker distribution:
COPY --from=komar007/cargo-lock-fetch \
/cargo-lock-fetch /usr/local/cargo/bin
It's also possible to build from source:
cargo install cargo-lock-fetch
or install a binary release from github:
cargo binstall cargo-lock-fetch # requires cargo-binstall
Important
For reproducible builds, avoid omitting version requirements when specifying dependencies. See [SemVer compatibility](#semver-compatibility) for semver guarantees. For `cargo` `install`/`binstall` use `[email protected]`, for docker images, use specific tag: `komar007/cargo-lock-fetch:0.x.y`.
To fetch dependencies to cargo’s registry cache:
cargo lock-fetch --lockfile-path path/to/Cargo.lock
To additionally vendor the dependencies (like cargo vendor):
cargo lock-fetch --lockfile-path path/to/Cargo.lock --vendor vendor_dir/
There is no need to run cargo lock-fetch from any specific directory.
This tool follows the cargo /
semver guidelines with respect to its CLI interface. At the current
0.x.y stage, changes of x (MINOR) indicate breaking changes. cargo-lock-fetch is close to
declaring a public interface which will be indicated by reaching version 1.0.0. From this moment,
breaking changes to the CLI interface will be indicated by MAJOR version increments.
The following example is the reason this plugin was written.
Assuming the Dockerfile is in the root directory of a cargo project, a minimal setup that caches
project dependencies in a docker layer and rebuilds it only on Cargo.lock changes would look like
this:
FROM rust:1.88.0-alpine3.22 AS builder
# Tools layer
RUN apk update \
&& apk add --no-cache musl-dev \
&& cargo install cargo-lock-fetch
WORKDIR /app
# Dependencies layer: fetch all dependencies, but only rebuild layer
# when Cargo.lock changes.
#
# This is for demonstration only - using cargo-lock-fetch starts to
# matter only when multiple Cargo.toml files are used because the
# project consists of many crates. It eliminates the need to specify
# each and every Cargo.toml file to be copied into the build context.
COPY Cargo.lock .
RUN cargo lock-fetch
# Sources layer: the build runs offline here. This layer rebuilds when
# any file changes, but dependencies are cached in the previous layer.
COPY . .
RUN cargo build --frozen --release
FROM scratch
COPY --from=builder /app/target/release/app /app
CMD [ "/app" ]
The example can be tested with docker compose build in examples/fetch-deps-to-layer.
In order to use cargo to fetch the crates, cargo-lock-fetch creates a cargo package and adds the
dependencies found in the input Cargo.lock file to its Cargo.toml, and then calls cargo fetch
and optionally cargo vendor.
Because a single Cargo.toml file cannot contain multiple versions of the same crate as
dependencies, and this situation is perfectly correct for cargo packages if the versions are pulled
in indirectly by different dependencies, cargo-lock-fetch distributes the list of dependencies
between sub-crates using an approach based on greedy vertex coloring, which is optimal for cluster
graphs (there is an edge between 2 dependencies iff they are different versions of the same crate).
Content type
Image
Digest
sha256:4c6ae9db3…
Size
1.7 MB
Last updated
3 months ago
docker pull komar007/cargo-lock-fetch