{"id":13502955,"url":"https://github.com/LukeMathWalker/cargo-chef","last_synced_at":"2025-03-29T12:33:18.319Z","repository":{"id":38375118,"uuid":"305468604","full_name":"LukeMathWalker/cargo-chef","owner":"LukeMathWalker","description":"A cargo-subcommand to speed up Rust Docker builds using Docker layer caching.","archived":false,"fork":false,"pushed_at":"2025-01-28T20:04:22.000Z","size":323,"stargazers_count":2020,"open_issues_count":38,"forks_count":120,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-03-25T19:15:09.712Z","etag":null,"topics":["cargo","ci","docker","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LukeMathWalker.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-10-19T17:52:16.000Z","updated_at":"2025-03-25T15:44:46.000Z","dependencies_parsed_at":"2023-02-10T04:16:08.429Z","dependency_job_id":"20b55889-f5ce-4716-b3e3-c624a39c85de","html_url":"https://github.com/LukeMathWalker/cargo-chef","commit_stats":{"total_commits":218,"total_committers":54,"mean_commits":4.037037037037037,"dds":0.6834862385321101,"last_synced_commit":"f0afda0ce176dc246d85bb553a45221d5129451c"},"previous_names":[],"tags_count":62,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LukeMathWalker%2Fcargo-chef","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LukeMathWalker%2Fcargo-chef/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LukeMathWalker%2Fcargo-chef/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LukeMathWalker%2Fcargo-chef/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LukeMathWalker","download_url":"https://codeload.github.com/LukeMathWalker/cargo-chef/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246187190,"owners_count":20737459,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cargo","ci","docker","rust"],"created_at":"2024-07-31T22:02:31.689Z","updated_at":"2025-03-29T12:33:18.297Z","avatar_url":"https://github.com/LukeMathWalker.png","language":"Rust","readme":"\u003ch1 align=\"center\"\u003ecargo-chef\u003c/h1\u003e\n\u003cdiv align=\"center\"\u003e\n \u003cstrong\u003e\n   Cache the dependencies of your Rust project and speed up your Docker builds.\n \u003c/strong\u003e\n\u003c/div\u003e\n\n\u003cbr /\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003c!-- Crates version --\u003e\n  \u003ca href=\"https://crates.io/crates/cargo-chef\"\u003e\n    \u003cimg src=\"https://img.shields.io/crates/v/cargo-chef.svg?style=flat-square\"\n    alt=\"Crates.io version\" /\u003e\n  \u003c/a\u003e\n  \u003c!-- Downloads --\u003e\n  \u003ca href=\"https://crates.io/crates/cargo-chef\"\u003e\n    \u003cimg src=\"https://img.shields.io/crates/d/cargo-chef.svg?style=flat-square\"\n      alt=\"Download\" /\u003e\n  \u003c/a\u003e\n\u003c/div\u003e\n\u003cbr/\u003e\n\n\u003e `cargo-chef` was initially developed for the deployment chapter of [Zero to Production In Rust](https://zero2prod.com), a hands-on introduction to backend development using the Rust programming language.\n\n# Table of Contents\n0. [How to install](#how-to-install)\n1. [How to use](#how-to-use)\n2. [Benefits vs Limitations](#benefits-vs-limitations)\n3. [License](#license)\n\n## How To Install \n\nYou can install `cargo-chef` from [crates.io](https://crates.io) with\n\n```bash\ncargo install cargo-chef --locked\n```\n\n## How to use\n\n\u003e :warning:  **cargo-chef is not meant to be run locally**  \n\u003e Its primary use-case is to speed up container builds by running BEFORE\n\u003e the actual source code is copied over. Don't run it on existing codebases to avoid\n\u003e having files being overwritten.\n\n`cargo-chef` exposes two commands: `prepare` and `cook`:\n\n```bash\ncargo chef --help\n```\n\n```text\n\ncargo-chef\n\nUSAGE:\n    cargo chef \u003cSUBCOMMAND\u003e\n\nSUBCOMMANDS:\n    cook       Re-hydrate the minimum project skeleton identified by `cargo chef prepare` and\n               build it to cache dependencies\n    prepare    Analyze the current project to determine the minimum subset of files (Cargo.lock\n               and Cargo.toml manifests) required to build it and cache dependencies\n```\n\n`prepare` examines your project and builds a _recipe_ that captures the set of information required to build your dependencies.\n\n```bash\ncargo chef prepare --recipe-path recipe.json\n```\n\nNothing 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.  \n 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).\n \nThe `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:\n\n```bash\ncargo chef cook --recipe-path recipe.json\n```\n\nIf you want to build in `--release` mode:\n\n```bash\ncargo chef cook --release --recipe-path recipe.json\n```\n\nYou can also choose to override which Rust toolchain should be used. E.g., to force the `nightly` toolchain:\n\n```bash\ncargo +nightly chef cook --recipe-path recipe.json\n```\n\n`cargo-chef` is designed to be leveraged in Dockerfiles:\n\n```dockerfile\nFROM lukemathwalker/cargo-chef:latest-rust-1 AS chef\nWORKDIR /app\n\nFROM chef AS planner\nCOPY . .\nRUN cargo chef prepare --recipe-path recipe.json\n\nFROM chef AS builder \nCOPY --from=planner /app/recipe.json recipe.json\n# Build dependencies - this is the caching Docker layer!\nRUN cargo chef cook --release --recipe-path recipe.json\n# Build application\nCOPY . .\nRUN cargo build --release --bin app\n\n# We do not need the Rust toolchain to run the binary!\nFROM debian:bookworm-slim AS runtime\nWORKDIR /app\nCOPY --from=builder /app/target/release/app /usr/local/bin\nENTRYPOINT [\"/usr/local/bin/app\"]\n```\n\nWe are using three stages: the first computes the recipe file, the second caches our dependencies and builds the binary, the third is our runtime environment.  \nAs long as your dependencies do not change the `recipe.json` file will stay the same, therefore the outcome of `cargo chef cook --release --recipe-path recipe.json` will be cached, massively speeding up your builds (up to 5x measured on some commercial projects).\n\n### Pre-built images\n\nWe offer `lukemathwalker/cargo-chef` as a pre-built Docker image equipped with both Rust and `cargo-chef`.\n\nThe tagging scheme is `\u003ccargo-chef version\u003e-rust-\u003crust version\u003e`.  \nFor example, `0.1.22-rust-1.56.0`.  \nYou can choose to get the latest version of either `cargo-chef` or `rust` by using:\n- `latest-rust-1.56.0` (use latest `cargo-chef` with specific Rust version);\n- `0.1.22-rust-latest` (use latest Rust with specific `cargo-chef` version).\nYou can find [all the available tags on Dockerhub](https://hub.docker.com/r/lukemathwalker/cargo-chef).\n\n\u003e :warning:  **You must use the same Rust version in all stages**  \n\u003e If you use a different Rust version in one of the stages\n\u003e caching will not work as expected.\n  \n### Without the pre-built image\n\nIf you do not want to use the `lukemathwalker/cargo-chef` image, you can simply install the CLI within the Dockerfile:\n\n```dockerfile\nFROM rust:1 AS chef \n# We only pay the installation cost once, \n# it will be cached from the second build onwards\nRUN cargo install cargo-chef \nWORKDIR app\n\nFROM chef AS planner\nCOPY . .\nRUN cargo chef prepare  --recipe-path recipe.json\n\nFROM chef AS builder\nCOPY --from=planner /app/recipe.json recipe.json\n# Build dependencies - this is the caching Docker layer!\nRUN cargo chef cook --release --recipe-path recipe.json\n# Build application\nCOPY . .\nRUN cargo build --release --bin app\n\n# We do not need the Rust toolchain to run the binary!\nFROM debian:bookworm-slim AS runtime\nWORKDIR app\nCOPY --from=builder /app/target/release/app /usr/local/bin\nENTRYPOINT [\"/usr/local/bin/app\"]\n```\n\n### Running the binary in Alpine\n\nIf you want to run your application using the `alpine` distribution you need to create a fully static binary.  \nThe recommended approach is to build for the `x86_64-unknown-linux-musl` target using [`muslrust`](https://github.com/clux/muslrust).  \n`cargo-chef` works for `x86_64-unknown-linux-musl`, but we are **cross-compiling** - the target\ntoolchain must be explicitly specified.\n\nA sample Dockerfile looks like this:\n\n```dockerfile\n# Using the `rust-musl-builder` as base image, instead of \n# the official Rust toolchain\nFROM clux/muslrust:stable AS chef\nUSER root\nRUN cargo install cargo-chef\nWORKDIR /app\n\nFROM chef AS planner\nCOPY . .\nRUN cargo chef prepare --recipe-path recipe.json\n\nFROM chef AS builder\nCOPY --from=planner /app/recipe.json recipe.json\n# Notice that we are specifying the --target flag!\nRUN cargo chef cook --release --target x86_64-unknown-linux-musl --recipe-path recipe.json\nCOPY . .\nRUN cargo build --release --target x86_64-unknown-linux-musl --bin app\n\nFROM alpine AS runtime\nRUN addgroup -S myuser \u0026\u0026 adduser -S myuser -G myuser\nCOPY --from=builder /app/target/x86_64-unknown-linux-musl/release/app /usr/local/bin/\nUSER myuser\nCMD [\"/usr/local/bin/app\"]\n```\n\n## Benefits vs Limitations\n\n`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](https://github.com/LukeMathWalker/cargo-chef).\n\n### Benefits of `cargo-chef`:\n\nA 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](https://www.lpalmieri.com/posts/fast-rust-docker-builds/#caching-rust-builds)). This is fragile compared to `cargo-chef` which will instead:\n\n- automatically pick up all crates in a workspace (and new ones as they are added)\n- keep working when files or crates are moved around, which would instead require manual edits to the `Dockerfile` using the \"manual\" approach\n- generate fewer intermediate Docker layers (for workspaces)\n\n### Limitations and caveats:\n\n- `cargo chef 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;\n- `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](https://github.com/rust-lang/cargo/issues/2644));\n\n## License\n\nLicensed under either of Apache License, Version 2.0 or MIT license at your option.\nUnless 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.\n","funding_links":[],"categories":["Rust","Development tools","开发工具 Development tools","虚拟化"],"sub_categories":["Deployment","部署 Deployment","部署"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLukeMathWalker%2Fcargo-chef","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FLukeMathWalker%2Fcargo-chef","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLukeMathWalker%2Fcargo-chef/lists"}