| Crates.io | cargo-green |
| lib.rs | cargo-green |
| version | 0.22.0 |
| created_at | 2024-05-11 10:27:16.385342+00 |
| updated_at | 2025-11-14 20:22:18.963547+00 |
| description | Cargo plugin and $RUSTC_WRAPPER to sandbox & cache cargo builds and execute jobs remotely |
| homepage | |
| repository | https://github.com/fenollp/supergreen |
| max_upload_size | |
| id | 1236783 |
| size | 412,278 |
supergreen ~ Faster Rust builds!cargo-green: a cached & remote-ready Rust projects builder.
cargo-green is
a cargo plugin that sets a $RUSTC_WRAPPER then calls cargo.
a RUSTC_WRAPPER that builds Dockerfiles
by forwarding rustc calls to BuildKit builders

$CARGOGREEN_LOG_PATH$CARGOGREEN_LOG$CARGOGREEN_LOG_STYLE$CARGOGREEN_RUNNER$BUILDX_BUILDER$CARGOGREEN_BUILDER_IMAGE$CARGOGREEN_SYNTAX_IMAGE$CARGOGREEN_REGISTRY_MIRRORS$CARGOGREEN_CACHE_IMAGES$CARGOGREEN_CACHE_FROM_IMAGES$CARGOGREEN_CACHE_TO_IMAGES$CARGOGREEN_FINAL_PATH$CARGOGREEN_BASE_IMAGE$CARGOGREEN_SET_ENVS$CARGOGREEN_BASE_IMAGE_INLINE$CARGOGREEN_WITH_NETWORK$CARGOGREEN_ADD_APT$CARGOGREEN_ADD_APT_GET$CARGOGREEN_ADD_APK$CARGOGREEN_EXPERIMENTcargo install cargo-green
cargo install --locked --force --git https://github.com/fenollp/supergreen.git cargo-green
# Make sure $CARGO_HOME/bin is in your $PATH
which cargo-green
When building locally, ensure either a docker or podman client is installed.
Minimum requirements:
Ubuntu 22.04buildkit 0.12.0github.com/docker/buildx v0.11.2rust 1.73# Usage:
cargo green supergreen env [ENV ...] Show used values
cargo green supergreen doc [ENV ...] Documentation of said values
cargo green fetch Pulls images
cargo green supergreen push Push cache image (all tags)
cargo green supergreen builder [ recreate | rm ] Manage local/remote builder(s)
cargo green supergreen -h | --help
cargo green supergreen -V | --version
cargo green ...any cargo subcommand...
# Try:
cargo clean # Start from a clean slate
cargo green build
cargo supergreen env CARGOGREEN_BASE_IMAGE 2>/dev/null
cargo supergreen help
# Suggestion:
alias cargo='cargo green'
# Now try, within your project:
cargo fetch
cargo test
Say you have a bigger machine in your ~/.ssh/config called extra-oomph:
DOCKER_HOST=ssh://extra-oomph cargo green test
This will compile the tests on the remote machine and run then locally.
TODO: also run tests remotely, like cross does: https://github.com/cross-rs/cross/blob/49cd054de9b832dfc11a4895c72b0aef533b5c6a/README.md#supported-targets
For more knobs to tune, see also:
Share your build cache with your team and CI, never feel cold starts!
[package.metadata.green]
cache-images = [ "docker-image://my.org/team/my-project", "docker-image://ghcr.io/me/fork" ]
cache-from-images = [ "docker-image://some.org/global/cache" ]
Tune the behavior of cargo-green either through environment variables or via the package's green metadata section.
[package]
name = "my-crate"
# ...
[package.metadata.green]
registry-mirrors = [ "mirror.gcr.io", "public.ecr.aws/docker" ] # Default values
Environment variables that are prefixed with $CARGOGREEN_ override TOML settings.
export CARGOGREEN_REGISTRY_MIRRORS=mirror.gcr.io
cargo green build
$CARGOGREEN_LOG_PATHPath to a text file to write logs.
Use by setting this environment variable (no Cargo.toml setting):
export CARGOGREEN_LOG_PATH="/tmp/my-logs.txt"
# This needs to be set: nothing is logged by default
export CARGOGREEN_LOG="info"
$CARGOGREEN_LOGFilter logs. Equivalent to $RUST_LOG (and doesn't conflict with cargo's).
By default, writes logs under /tmp.
See https://docs.rs/env_logger/#enabling-logging
Use by setting this environment variable (no Cargo.toml setting):
export CARGOGREEN_LOG="trace,cargo_green::build=info"
$CARGOGREEN_LOG_STYLEStyle logs. Equivalent to $RUST_LOG_STYLE.
See https://docs.rs/env_logger/#disabling-colors
Use by setting this environment variable (no Cargo.toml setting):
export CARGOGREEN_LOG_STYLE="never"
$CARGOGREEN_RUNNERPick which executor to use: "docker" (default), "podman" or "none".
The runner gets forwarded these environment variables:
$BUILDKIT_COLORS$BUILDKIT_HOST$BUILDKIT_PROGRESS$BUILDKIT_TTY_LOG_LINES$BUILDX_BAKE_GIT_AUTH_HEADER$BUILDX_BAKE_GIT_AUTH_TOKEN$BUILDX_BAKE_GIT_SSH$BUILDX_BUILDER$DOCKER_BUILDKIT$BUILDX_CONFIG$BUILDX_CPU_PROFILE$BUILDX_EXPERIMENTAL$BUILDX_GIT_CHECK_DIRTY$BUILDX_GIT_INFO$BUILDX_GIT_LABELS$BUILDX_MEM_PROFILE$BUILDX_METADATA_PROVENANCE$BUILDX_METADATA_WARNINGS$BUILDX_NO_DEFAULT_ATTESTATIONS$BUILDX_NO_DEFAULT_LOAD$DOCKER_API_VERSION$DOCKER_CERT_PATH$DOCKER_CONFIG$DOCKER_CONTENT_TRUST$DOCKER_CONTENT_TRUST_SERVER$DOCKER_CONTEXT$DOCKER_DEFAULT_PLATFORM$DOCKER_HIDE_LEGACY_COMMANDS$DOCKER_HOST$DOCKER_TLS$DOCKER_TLS_VERIFY$EXPERIMENTAL_BUILDKIT_SOURCE_POLICY$HTTP_PROXY$HTTPS_PROXY$NO_PROXYUse by setting this environment variable (no Cargo.toml setting):
export CARGOGREEN_RUNNER="docker"
$BUILDX_BUILDERSets which BuildKit builder to use, through $BUILDX_BUILDER.
See https://docs.docker.com/build/building/variables/#buildx_builder
"supergreen". Upgrades it if too old, while trying to keep old cached data"": skips using a builder"supergreen": uses existing and just warns if too oldSee also
$DOCKER_HOST: https://docs.docker.com/engine/reference/commandline/cli/#environment-variables$DOCKER_CONTEXT: https://docs.docker.com/reference/cli/docker/#environment-variables$BUILDKIT_HOST: https://docs.docker.com/build/building/variables/#buildkit_host$CARGOGREEN_BUILDER_IMAGESets which BuildKit builder version to use.
See https://docs.docker.com/build/builders/
Use by setting this environment variable (no Cargo.toml setting):
export CARGOGREEN_BUILDER_IMAGE="docker-image://docker.io/moby/buildkit:latest"
$CARGOGREEN_SYNTAX_IMAGESets which BuildKit frontend syntax to use.
See https://docs.docker.com/build/buildkit/frontend/#stable-channel
Use by setting this environment variable (no Cargo.toml setting):
export CARGOGREEN_SYNTAX_IMAGE="docker-image://docker.io/docker/dockerfile:1"
$CARGOGREEN_REGISTRY_MIRRORSRegistry mirrors for Docker Hub (docker.io). Defaults to GCP & AWS mirrors.
See https://docs.docker.com/build/buildkit/configure/#registry-mirror
Namely hosts with maybe a port and a path:
dockerhub.timeweb.clouddockerhub1.beget.comlocalhost:5000mirror.gcr.iopublic.ecr.aws/dockerregistry-mirrors = [ "mirror.gcr.io", "public.ecr.aws/docker" ]
This environment variable takes precedence over any Cargo.toml settings:
# Note: values here are comma-separated.
export CARGOGREEN_REGISTRY_MIRRORS="mirror.gcr.io,public.ecr.aws/docker"
$CARGOGREEN_CACHE_IMAGESBoth read and write cached data to and from image registries
Exactly a combination of [Green::cache_from_images] and [Green::cache_to_images].
See
type=registry at https://docs.docker.com/build/cache/backends/cache-images = [ "docker-image://my.org/team/my-project", "docker-image://some.org/global/cache" ]
This environment variable takes precedence over any Cargo.toml settings:
# Note: values here are comma-separated.
export CARGOGREEN_CACHE_IMAGES="docker-image://my.org/team/my-project,docker-image://some.org/global/cache"
$CARGOGREEN_CACHE_FROM_IMAGESRead cached data from image registries
See also [Green::cache_images] and [Green::cache_to_images].
cache-from-images = [ "docker-image://my.org/team/my-project-in-ci", "docker-image://some.org/global/cache" ]
This environment variable takes precedence over any Cargo.toml settings:
# Note: values here are comma-separated.
export CARGOGREEN_CACHE_FROM_IMAGES="docker-image://my.org/team/my-project-in-ci,docker-image://some.org/global/cache"
$CARGOGREEN_CACHE_TO_IMAGESWrite cached data to image registries
Note that errors caused by failed cache exports are not ignored.
See also [Green::cache_images] and [Green::cache_from_images].
cache-to-images = [ "docker-image://my.org/team/my-fork" ]
This environment variable takes precedence over any Cargo.toml settings:
# Note: values here are comma-separated.
export CARGOGREEN_CACHE_TO_IMAGES="docker-image://my.org/team/my-fork"
$CARGOGREEN_FINAL_PATHWrite final containerfile to given path.
Helps e.g. create a containerfile of e.g. a binary to use for best caching of dependencies.
Use by setting this environment variable (no Cargo.toml setting):
export CARGOGREEN_FINAL_PATH="$PWD/my-bin@1.0.0.Dockerfile"
$CARGOGREEN_BASE_IMAGESets the base Rust image, as an image URL (or any build context, actually).
If needing additional envs to be passed to rustc or build script, set them in the base image.
This can be done in that same config file with base-image-inline.
See also:
also-runbase-image-inlineadditional-build-argumentsFor remote builds: make sure this is accessible non-locally.
base-image = "docker-image://docker.io/library/rust:1-slim"
The value must start with docker-image:// and image must be available on the $DOCKER_HOST, eg:
export CARGOGREEN_BASE_IMAGE=docker-image://rustc_with_libs
DOCKER_HOST=ssh://my-remote-builder docker buildx build -t rustc_with_libs - <<EOF
FROM docker.io/library/rust:1.69.0-slim-bookworm@sha256:8bdd28ef184d85c9b4932586af6280732780e806e5f452065420f2e783323ca3
RUN set -eux && apt update && apt install -y libpq-dev libssl3
ENV KEY=value
EOF
This environment variable takes precedence over any Cargo.toml settings:
export CARGOGREEN_BASE_IMAGE="docker-image://docker.io/library/rust:1-slim"
$CARGOGREEN_SET_ENVSPass environment variables through to build runner.
May be useful if a build script exported some vars that a package then reads. See also:
packagesSee about $GIT_AUTH_TOKEN: https://docs.docker.com/build/building/secrets/#git-authentication-for-remote-contexts
NOTE: this doesn't (yet) accumulate dependencies' set-envs values! Meaning only the top-level crate's setting is used, for all crates/dependencies.
set-envs = [ "GIT_AUTH_TOKEN", "TYPENUM_BUILD_CONSTS", "TYPENUM_BUILD_OP" ]
This environment variable takes precedence over any Cargo.toml settings:
# Note: values here are comma-separated.
export CARGOGREEN_SET_ENVS="GIT_AUTH_TOKEN,TYPENUM_BUILD_CONSTS,TYPENUM_BUILD_OP"
$CARGOGREEN_BASE_IMAGE_INLINESets the base Rust image for root package and all dependencies, unless themselves being configured differently.
See also:
with-networkadditional-build-argumentsIn order to avoid unexpected changes, you may want to pin the image using an immutable digest.
Note that carefully crafting crossplatform stages can be non-trivial.
base-image-inline = """
FROM --platform=$BUILDPLATFORM rust:1 AS rust-base
RUN --mount=from=some-context,dst=/tmp/some-context cp -r /tmp/some-context ./
RUN --mount=type=secret,id=aws
"""
# This must also be set so digest gets pinned automatically.
base-image = "docker-image://rust:1"
This environment variable takes precedence over any Cargo.toml settings:
IFS='' read -r -d '' CARGOGREEN_BASE_IMAGE_INLINE <<"EOF"
FROM rust:1 AS rust-base
RUN --mount=from=some-context,dst=/tmp/some-context cp -r /tmp/some-context ./
RUN --mount=type=secret,id=aws
EOF
echo "$CARGOGREEN_BASE_IMAGE_INLINE" # (with quotes to preserve newlines)
export CARGOGREEN_BASE_IMAGE_INLINE
export CARGOGREEN_BASE_IMAGE=docker-image://rust:1
$CARGOGREEN_WITH_NETWORKControls runner's --network none (default) | default | host setting.
Set this to "default" if e.g. your base-image-inline calls curl or wget or installs some packages.
Set to none when in $CARGO_NET_OFFLINE mode. See
This environment variable takes precedence over any Cargo.toml settings:
export CARGOGREEN_WITH_NETWORK="none"
$CARGOGREEN_ADD_APTAdds OS packages to the base image with apt install.
See also:
add.apkadd.apt-getbase-image[package.metadata.green]
add.apt = [ "libpq-dev", "pkg-config" ]
This environment variable takes precedence over any Cargo.toml settings:
# Note: values here are comma-separated.
export CARGOGREEN_ADD_APT="libpq-dev,pkg-config"
# Inspect the resulting base image with:
cargo green supergreen env CARGOGREEN_BASE_IMAGE_INLINE
$CARGOGREEN_ADD_APT_GETAdds OS packages to the base image with apt-get install.
See also:
add.apkadd.aptbase-imageadd.apt-get = [ "libpq-dev", "pkg-config" ]
This environment variable takes precedence over any Cargo.toml settings:
# Note: values here are comma-separated.
export CARGOGREEN_ADD_APT_GET="libpq-dev,pkg-config"
# Inspect the resulting base image with:
cargo green supergreen env CARGOGREEN_BASE_IMAGE_INLINE
$CARGOGREEN_ADD_APKAdds OS packages to the base image with apk add.
See also:
add.aptadd.apt-getbase-imageadd.apk = [ "libpq-dev", "pkgconf" ]
This environment variable takes precedence over any Cargo.toml settings:
# Note: values here are comma-separated.
export CARGOGREEN_ADD_APK="libpq-dev,pkg-conf"
# Inspect the resulting base image with:
cargo green supergreen env CARGOGREEN_BASE_IMAGE_INLINE
$CARGOGREEN_EXPERIMENTA comma-separated list of names of features to activate.
A name that does not match exactly is an error.
finalpathnonprimary:
incremental:
repro:
Use by setting this environment variable (no Cargo.toml setting):
export CARGOGREEN_EXPERIMENT="finalpathnonprimary,repro"
In no particular order:
crane: A Nix library for building cargo projects. Never build twice thanks to incremental artifact caching.
=> Very complete! Relies on nix tools and language.sccache: sccache - Shared Compilation Cache
=> Relies on everyone having the same paths and doesn't cache all crate types.distrustc: A Rust-compatible distcc implementation
cargo-chef: A cargo-subcommand to speed up Rust Docker builds using Docker layer caching.
=> Relies on everyone having the same paths + cache isn't crate-granular.rules_rust: Rules Rust
=> Replaces cargo with bazel.cargo-remote: cargo subcommand to compile rust projects remotely
=> Uses rsync and ssh; seems unmaintained.rust-cache: A GitHub Action that implements smart caching for rust/cargo projects
=> A GitHub Action.cargo-cross: “Zero setup” cross compilation and “cross testing” of Rust crates
=> seldomly maintained but a lifesaver for cross compilation.
See also this article on what cargo-green does (perfect layering):./hack/cli.sh ...# Usage: $0 #=> generate CI
#
# Usage: $0 ( <name@version> | <name> ) #=> cargo install name@version
# Usage: $0 ok #=> cargo install all working bins
#
# Usage: $0 ( build | test ) #=> cargo build ./cargo-green
#
# Usage: jobs=1 $0 .. #=> cargo --jobs=$jobs
# Usage: offline=1 $0 .. #=> cargo --frozen (defaults to just: --locked)
# Usage: rmrf=1 $0 .. #=> rm -rf $CARGO_TARGET_DIR/*; cargo ...
# Usage: reset=1 $0 .. #=> docker buildx rm $BUILDX_BUILDER; cargo ...
# Usage: clean=1 $0 .. #=> Both reset=1 + rmrf=1
# Usage: final=1 $0 .. #=> Generate final Containerfile
#
# Usage: DOCKER_HOST=.. $0 .. #=> Overrides machine
# Usage: BUILDX_BUILDER=.. $0 .. #=> Overrides builder (set to "empty" to set BUILDX_BUILDER='')
./hack/recipes.shSyncs ./recipes/*.Dockerfile files.
./hack/caching.shVerifies properties about caching crates & granularity.
docker buildx prune --all --force
./hack/hit.shEstimate of amount of crates reused through compilation of ./recipes/ --> ~5%!
Expecting more with larger/more representative corpus + smart locking of transitive deps.
recipes/buildxargs@1.4.0.Dockerfile
8< 8< 8<
3: dep-l-utf8parse-0.2.1-522ff71b25340e24
5: dep-l-bitflags-1.3.2-70ce9f1f2fa253bc
5: dep-l-strsim-0.10.0-fd42a4ea370e31ec
5: dep-l-unicode-ident-1.0.12-4c1dc76c11b3deb8
6: dep-l-cfg-if-1.0.0-da34da6838abd7f1
Total recipes: 15
Total stages: 1065
Stages in common: 58
5.44%
git-bisectingall:
cargo +nightly fmt --all
./hack/clis.sh | tee .github/workflows/clis.yml
./hack/self.sh | tee .github/workflows/self.yml
CARGO_TARGET_DIR=$${CARGO_TARGET_DIR:-target/clippy} cargo clippy --locked --frozen --offline --all-targets --all-features -- --no-deps -W clippy::cast_lossless -W clippy::redundant_closure_for_method_calls -W clippy::str_to_string -W clippy::unnecessary_wraps
RUST_MIN_STACK=8000000 cargo nextest run --all-targets --all-features --locked --frozen --offline --no-fail-fast
git --no-pager diff --exit-code
DOCKER_HOST= with e.g. ssh://me@beaffy-machine.internal.net
cargo usage
cargo doesrustc anytime
rustc does necessitate a fresh buildrustc calls in buildkit-like calls (docker, podman)
dockerpodman TODO: test in CIcrater)
C deps.dockerignores (to be authoritative on srcs)rustc wrapper through $RUSTC_WRAPPERcargo subcommand
rustc version
rustc base imagemold, ...)
Dockerfile stage?[SEC] support building a crate without it having network accessuser-wide-cache
rustc, ...)
Cargo.lock (changes on every release cut!)WORKDIRs + rewrite paths with remap-path-prefix[SEC] ensure private deps don't leak through/to cachecargo install's any cratecross
build for a non-local target
run/test for a non-local target (with cross's same caveats ie. QEMU)
cargo: Tell rustc wrappers which envs to pass through to allow env sandboxing
gRPC buffers too small
buildkit: Build function: ResourceExhausted: grpc: received message larger than max (_ vs. 4194304)buildx: ResourceExhausted: grpc: received message larger than max (_ vs. 4194304)buildkit: remote docker buildx build with large dockerfile gives trying to send message larger than max (22482550 vs. 16777216) error buildkit: Support extracting ADD --checksum=.. https://.. ..
buildkit: RUN --no-cache to skip reading & writing a RUN layer to cache
buildkit: Looking for a consistently "latest" BuildKit image tag
TODO
=1 stage per Dockerfile part file
Getting an image's digest fast, within a docker-container builder
buildkit: allow exporting cache layers in parallel to the remote registry
buildx: --cache-from takes longer than actual (cached) build
Proposal: c8d: expose contentstore API #44369 https://github.com/moby/moby/issues/44369
Incremental export transfer #1224 https://github.com/moby/buildkit/issues/1224
"sending tarball" takes a long time even when the image already exists #107 https://github.com/docker/buildx/issues/107
Build drivers https://docs.docker.com/build/drivers/
https://docs.docker.com/build/ci/github-actions/configure-builder/#max-parallelism
https://docs.docker.com/engine/reference/builder/#buildkit-built-in-build-args
tunnel tty into a docker build through http
docker build remote driver https://docs.docker.com/build/drivers/remote
rootless k8s driver https://docs.docker.com/build/drivers/kubernetes/#rootless-mode
tune many options https://docs.docker.com/build/drivers/docker-container/
https://docs.docker.com/build/attestations/sbom/
BUILDKIT_SBOM_SCAN_CONTEXT and BUILDKIT_SBOM_SCAN_STAGEprune: filtering out ADD --checksum=... https://... entries #2448
-o=.: open $HOME/.local/share/docker/overlay2/066f6../work/work: permission denied #2219
cargo restrict targets of crate
Target configuration for binaries #9208 https://github.com/rust-lang/cargo/issues/9208
Unsafe fields #3458 https://github.com/rust-lang/rfcs/pull/3458
Warning when large binary files are included into the bundle #9058 https://github.com/rust-lang/cargo/issues/9058
Hermetic build mode #9506 https://github.com/rust-lang/cargo/issues/9506
Feature Request static asserts #2790 https://github.com/rust-lang/rfcs/issues/2790
greater supply chain attack risk due to large dependency trees? https://www.reddit.com/r/rust/comments/102yz60/greater_supply_chain_attack_risk_due_to_large/
https://doc.rust-lang.org/rustc/command-line-arguments.html#option-emit
[build] rustflags = ["--remap-path-prefix"
/r/Rust scare Serde has started shipping precompiled binaries with no way to opt out
What's the best practice for caching compilation of Rust dependencies?
Everytime I try to use Tauri for Android... Why?
ultimately the "real" solution has got to be a complete overhaul of the entire compilation system to be entirely on-demand in a granular basis, rather than "compile every crate in the dependency tree wholesale".