All Projects → LukeMathWalker → Cargo Chef

LukeMathWalker / Cargo Chef

A cargo-subcommand to speed up Rust Docker builds using Docker layer caching.

Programming Languages

rust
11053 projects

Projects that are alternatives of or similar to Cargo Chef

Docker Test Openldap
Docker OpenLDAP Server for testing LDAP applications
Stars: ✭ 164 (-14.58%)
Mutual labels:  ci
Env Ci
Get environment variables exposed by CI services
Stars: ✭ 180 (-6.25%)
Mutual labels:  ci
Jest Canvas Mock
🌗 A module used to mock canvas in Jest.
Stars: ✭ 189 (-1.56%)
Mutual labels:  ci
Solo Ci
A lightweight CI/CD tool powered by Golang
Stars: ✭ 168 (-12.5%)
Mutual labels:  ci
Meuse
A private Cargo crate registry, for Rust
Stars: ✭ 173 (-9.9%)
Mutual labels:  cargo
Cargo Spellcheck
Checks all your documentation for spelling and grammar mistakes with hunspell and a nlprule based checker for grammar
Stars: ✭ 183 (-4.69%)
Mutual labels:  cargo
Semantic Rs
🚀 Automatic crate publishing done right
Stars: ✭ 162 (-15.62%)
Mutual labels:  cargo
Npmvet
A simple CLI tool for vetting npm package versions
Stars: ✭ 193 (+0.52%)
Mutual labels:  ci
Legacy Old Hercules
Abandoned
Stars: ✭ 174 (-9.37%)
Mutual labels:  ci
Cargo Play
A local Rust playground
Stars: ✭ 189 (-1.56%)
Mutual labels:  cargo
Nevergreen
🐤 A build monitor with attitude
Stars: ✭ 170 (-11.46%)
Mutual labels:  ci
Routerify
A lightweight, idiomatic, composable and modular router implementation with middleware support for the Rust HTTP library hyper.rs
Stars: ✭ 173 (-9.9%)
Mutual labels:  cargo
Mbt
The most flexible build tool for monorepo
Stars: ✭ 184 (-4.17%)
Mutual labels:  ci
Cargo Deps
Cargo subcommand for building dependency graphs of Rust projects
Stars: ✭ 168 (-12.5%)
Mutual labels:  cargo
Woke
✊ Detect non-inclusive language in your source code.
Stars: ✭ 190 (-1.04%)
Mutual labels:  ci
Codecov Python
Python report uploader for Codecov
Stars: ✭ 162 (-15.62%)
Mutual labels:  ci
Parameters
📊 Computation and processing of models' parameters
Stars: ✭ 181 (-5.73%)
Mutual labels:  ci
Naersk
Build rust crates in Nix. No configuration, no code generation, no IFD. Sandbox friendly.
Stars: ✭ 193 (+0.52%)
Mutual labels:  cargo
Poetry Calendar
✨🗓✨一个美炸天的诗词周历 , 52个周给你新的体验。
Stars: ✭ 192 (+0%)
Mutual labels:  ci
Wflow
🐆 EXPERIMENTAL -- Runs GitHub Actions workflows locally (local) -- Don't run your YAML like a 🐪
Stars: ✭ 187 (-2.6%)
Mutual labels:  ci

cargo-chef

Cache the dependencies of your Rust project and speed up your Docker builds.


Table of Contents

  1. How to install
  2. How to use
  3. Benefits vs Limitations
  4. License

How To Install

You can install cargo-chef from crates.io with

cargo install cargo-chef

How to use

⚠️ cargo-chef is not meant to be run locally
Its primary use-case is to speed up container builds by running BEFORE the actual source code is copied over. Don't run it on existing codebases to avoid having files being overwritten.

cargo-chef exposes two commands: prepare and cook:

cargo chef --help
cargo-chef

USAGE:
    cargo chef <SUBCOMMAND>

SUBCOMMANDS:
    cook       Re-hydrate the minimum project skeleton identified by `cargo chef prepare` and
               build it to cache dependencies
    prepare    Analyze the current project to determine the minimum subset of files (Cargo.lock
               and Cargo.toml manifests) required to build it and cache dependencies

prepare examines your project and builds a recipe that captures the set of information required to build your dependencies.

cargo chef prepare --recipe-path recipe.json

Nothing too mysterious going on here, you can examine the recipe.json file: it contains the skeleton of your project (e.g. all the Cargo.toml files with their relative path, the Cargo.lock file is available) plus a few additional pieces of information.
In particular it makes sure that all libraries and binaries are explicitly declared in their respective Cargo.toml files even if they can be found at the canonical default location (src/main.rs for a binary, src/lib.rs for a library).

The recipe.json is the equivalent of the Python requirements.txt file - it is the only input required for cargo chef cook, the command that will build out our dependencies:

cargo chef cook --recipe-path recipe.json

If you want to build in --release mode:

cargo chef cook --release --recipe-path recipe.json

You can leverage it in a Dockerfile:

FROM lukemathwalker/cargo-chef as planner
WORKDIR app
COPY . .
RUN cargo chef prepare  --recipe-path recipe.json

FROM lukemathwalker/cargo-chef as cacher
WORKDIR app
COPY --from=planner /app/recipe.json recipe.json
RUN cargo chef cook --release --recipe-path recipe.json

FROM rust as builder
WORKDIR app
COPY . .
# Copy over the cached dependencies
COPY --from=cacher /app/target target
COPY --from=cacher $CARGO_HOME $CARGO_HOME
RUN cargo build --release --bin app

FROM rust as runtime
WORKDIR app
COPY --from=builder /app/target/release/app /usr/local/bin
ENTRYPOINT ["/usr/local/bin/app"]

We are using four stages: the first computes the recipe file, the second caches our dependencies, the third builds the binary and the fourth is our runtime environment.
As long as your dependencies do not change the recipe.json file will stay the same, therefore the outcome of cargo cargo chef cook --release --recipe-path recipe.json will be cached, massively speeding up your builds (up to 5x measured on some commercial projects).

If you do not want to use the lukemathwalker/cargo-chef image, you can simply install the CLI within the Dockerfile:

FROM rust as planner
WORKDIR app
# We only pay the installation cost once, 
# it will be cached from the second build onwards
RUN cargo install cargo-chef 
COPY . .
RUN cargo chef prepare  --recipe-path recipe.json

FROM rust as cacher
WORKDIR app
RUN cargo install cargo-chef
COPY --from=planner /app/recipe.json recipe.json
RUN cargo chef cook --release --recipe-path recipe.json

FROM rust as builder
WORKDIR app
COPY . .
# Copy over the cached dependencies
COPY --from=cacher /app/target target
COPY --from=cacher $CARGO_HOME $CARGO_HOME
RUN cargo build --release --bin app

FROM rust as runtime
WORKDIR app
COPY --from=builder /app/target/release/app /usr/local/bin
ENTRYPOINT ["/usr/local/bin/app"]

Benefits vs Limitations

cargo-chef has been tested on a few OpenSource projects and some of commercial projects, but our testing has definitely not exhausted the range of possibilities when it comes to cargo build customisations and we are sure that there are a few rough edges that will have to be smoothed out - please file issues on GitHub.

Benefits of cargo-chef:

A common alternative is to load a minimal main.rs into a container with Cargo.toml and Cargo.lock to build a Docker layer that consists of only your dependencies (more info here). This is fragile compared to cargo-chef which will instead:

  • automatically pick up all crates in a workspace (and new ones as they are added)
  • keep working when files or crates are moved around, which would instead require manual edits to the Dockerfile using the "manual" approach
  • generate fewer intermediate Docker layers (for workspaces)

Limitations and caveats:

  • cargo cook and cargo build must be executed from the same working directory. If you examine the *.d files under target/debug/deps for one of your projects using cat you will notice that they contain absolute paths referring to the project target directory. If moved around, cargo will not leverage them as cached dependencies;
  • cargo build will build local dependencies (outside of the current project) from scratch, even if they are unchanged, due to the reliance of its fingerprinting logic on timestamps (see this long issue on cargo's repository);

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].