# rust A Docker image that ships the **latest stable Rust toolchain** (fetched from `static.rust-lang.org` at image build time, SHA256-verified) together with a comprehensive set of tools for building, testing, linting, formatting, debugging, profiling, fuzzing, and releasing Rust projects. Based on Alpine with full musl static-build support and 30 pre-installed cross-compile targets. --- ## ๐Ÿ“ฆ Pull ```shell docker pull casjaysdev/rust:latest ``` --- ## ๐Ÿš€ Install and run container ```shell dockermgr update rust ``` Or manually: ```shell dockerHome="/srv/$USER/docker/casjaysdevdocker/rust/rust/latest/volumes" mkdir -p "$dockerHome" git clone "https://github.com/dockermgr/rust" "$HOME/.local/share/CasjaysDev/dockermgr/rust" cp -Rfva "$HOME/.local/share/CasjaysDev/dockermgr/rust/rootfs/." "$dockerHome/" docker run -d \ --restart always \ --privileged \ --name casjaysdevdocker-rust-latest \ --hostname rust \ -e TZ=${TIMEZONE:-America/New_York} \ -v "$dockerHome/data:/data:z" \ -v "$dockerHome/config:/config:z" \ -v rust-cargo:/usr/local/share/cargo \ -v rust-rustup:/usr/local/share/rustup \ -v rust-sccache:/root/.cache/sccache \ casjaysdev/rust:latest ``` --- ## โšก rust-workflow **`rust-workflow`** is a four-step pipeline included in the image. It must be called explicitly โ€” running the container with no arguments starts it in monitoring mode, it does not execute `rust-workflow` automatically: ``` fmt check โ†’ clippy -D warnings โ†’ cargo test --all โ†’ cargo build --release ``` ```shell # run the full workflow against your project docker run --rm -it \ -v "$PWD:/app" \ casjaysdev/rust:latest rust-workflow ``` Override the working directory with `CARGO_WORKDIR`, or target a specific cross-compile triple with `CARGO_BUILD_TARGET`: ```shell docker run --rm -it \ -v "$PWD:/app" \ -e CARGO_BUILD_TARGET=aarch64-unknown-linux-musl \ casjaysdev/rust:latest rust-workflow ``` --- ## ๐Ÿณ Docker ### Quick one-shot commands ```shell # build release binary docker run --rm -it -v "$PWD:/app" casjaysdev/rust:latest \ cargo build --release # run tests with cargo-nextest docker run --rm -it -v "$PWD:/app" casjaysdev/rust:latest \ cargo nextest run # lint docker run --rm -it -v "$PWD:/app" casjaysdev/rust:latest \ cargo clippy --all-targets --all-features -- -D warnings # check formatting docker run --rm -it -v "$PWD:/app" casjaysdev/rust:latest \ cargo fmt --all -- --check # audit dependencies for known vulnerabilities docker run --rm -it -v "$PWD:/app" casjaysdev/rust:latest \ cargo audit # interactive shell docker run --rm -it -v "$PWD:/app" casjaysdev/rust:latest bash -l ``` ### Long-running container ```shell docker run -d \ --restart always \ --name casjaysdev-rust \ --hostname rust \ -e TZ=${TIMEZONE:-America/New_York} \ -v rust-cargo:/usr/local/share/cargo \ -v rust-rustup:/usr/local/share/rustup \ -v rust-sccache:/root/.cache/sccache \ -v "$PWD:/app" \ casjaysdev/rust:latest # exec into it docker exec -it casjaysdev-rust bash -l docker exec casjaysdev-rust cargo test docker exec casjaysdev-rust cargo clippy --all-targets docker exec casjaysdev-rust cargo nextest run docker exec casjaysdev-rust cargo audit ``` ### docker-compose ```yaml services: rust: image: casjaysdev/rust:latest container_name: casjaysdev-rust hostname: rust environment: - TZ=America/New_York volumes: - rust-cargo:/usr/local/share/cargo - rust-rustup:/usr/local/share/rustup - rust-sccache:/root/.cache/sccache - .:/app restart: always volumes: rust-cargo: rust-rustup: rust-sccache: ``` --- ## ๐Ÿ”ง Included tools ### Toolchain (via rustup โ€” stable) | Component | Purpose | |-----------|---------| | `rustc` | Rust compiler | | `cargo` | Package manager and build tool | | `rustfmt` | Official code formatter | | `clippy` | Lint collection โ€” catches correctness and style issues | | `rust-src` | Standard library source โ€” required by rust-analyzer and miri | | `rust-analyzer` | Language server โ€” IDE integration | | `llvm-tools-preview` | LLVM utilities โ€” used by coverage and binutils tools | ### Toolchain (via rustup โ€” nightly, minimal) | Component | Purpose | |-----------|---------| | `miri` | Interpreter that detects undefined behavior, borrow violations, and memory errors at runtime | | `rust-src` (nightly) | Required by miri | Run miri with: `cargo +nightly miri test` ### Linting & static analysis | Tool | Purpose | |------|---------| | `cargo-clippy` | Bundled with toolchain; `cargo clippy --all-targets --all-features` | | `cargo-geiger` | Counts `unsafe` blocks and dependencies โ€” reports unsafe surface area | | `cargo-deny` | Policy enforcement โ€” license allow-lists, ban crates, advisories | | `cargo-audit` | Scan `Cargo.lock` against the RustSec advisory DB | | `cargo-machete` | Detect unused dependencies (stable) | | `cargo-udeps` | Detect unused dependencies (nightly; `cargo +nightly udeps`) | | `cargo-hack` | Test all feature flag combinations to catch cfg-gated bugs | | `cargo-minimal-versions` | Verify the crate compiles with the minimum versions declared in `Cargo.toml` | | `cargo-semver-checks` | Detect breaking API changes against a published version | | `cargo-public-api` | Diff the public API between commits or versions | | `typos` | Fast source-code spell checker โ€” catches typos in identifiers and strings | | `cargo-spellcheck` | Doc-comment spell checker โ€” catches typos in `///` and `//!` docs | ### Formatting | Tool | Purpose | |------|---------| | `rustfmt` | Bundled; `cargo fmt --all` | | `taplo` | TOML formatter and linter โ€” format `Cargo.toml`, `.cargo/config.toml`, etc. | | `dprint` | Pluggable formatter โ€” supports Rust (via rustfmt plugin), TOML, JSON, Markdown | | `cargo-sort` | Sort `[dependencies]` sections in `Cargo.toml` alphabetically | ### Testing & coverage | Tool | Purpose | |------|---------| | `cargo-nextest` | Faster test runner โ€” parallel, per-test timeouts, JUnit output | | `cargo-llvm-cov` | Source-based code coverage using LLVM instrumentation | | `cargo-tarpaulin` | Coverage via ptrace โ€” useful when LLVM instrumentation isn't available | | `grcov` | Mozilla's LLVM coverage aggregator โ€” converts profraw data to lcov/HTML | | `cargo-mutants` | Mutation testing โ€” checks that tests actually catch code changes | | `miri` | Run tests under the interpreter to catch UB (see nightly above) | ### Benchmarking & profiling | Tool | Purpose | |------|---------| | `cargo-criterion` | Criterion-based benchmark runner with statistical analysis | | `hyperfine` | Command-line benchmarking tool โ€” wall-clock timing with statistics | | `samply` | Sampling profiler โ€” records perf profiles, opens in Firefox Profiler | | `flamegraph` | Generate flame graphs from `cargo bench` or any cargo command (`cargo flamegraph`) | > **Perf note:** `perf` is installed from the Alpine package repo. Profiling with > `samply` or `flamegraph` inside Docker requires elevated capabilities at runtime: > `--privileged` or `--cap-add SYS_ADMIN --cap-add PERFMON`. This is a host grant > โ€” it cannot be baked into the image. ### Fuzzing | Tool | Purpose | |------|---------| | `cargo-fuzz` | libFuzzer integration for Rust โ€” `cargo fuzz run ` | ### Debugging | Tool | Purpose | |------|---------| | `gdb` | GNU debugger โ€” `rust-gdb` wrapper is provided by the toolchain | | `miri` | Undefined-behavior detector โ€” catches memory errors before they reach gdb | | `cargo-careful` | Run tests and binaries with extra UB checks (`-Z randomize-layout`, `panic-on-ub`) | | `probe-rs` | On-chip debugger for embedded targets โ€” flashes and debugs ARM/RISC-V | ### Code analysis & inspection | Tool | Purpose | |------|---------| | `cargo-expand` | Expand proc-macros and `macro_rules!` to plain Rust | | `cargo-asm` | Disassemble a function to see the emitted assembly | | `cargo-bloat` | Identify what is taking space in your binary | | `cargo-binutils` | `llvm-size`, `llvm-nm`, `llvm-objdump`, etc. via `cargo-` wrappers | | `tokei` | Count lines of code by language | ### Build & release | Tool | Purpose | |------|---------| | `cargo-make` | Task runner (`Makefile.toml`) โ€” replaces `make` for Rust projects | | `just` | Command runner (`justfile`) โ€” simpler `make` alternative | | `cargo-release` | Automate version bumps, changelog, tag, and publish | | `cargo-dist` | Cross-platform release artifact builder and installer generator | | `cargo-deb` | Build `.deb` packages directly from `Cargo.toml` | | `cargo-generate` | Scaffold new crates from templates | | `cargo-chef` | Docker layer caching for Cargo builds โ€” pre-cook dependencies | ### Cross-compilation | Tool | Purpose | |------|---------| | `cargo-zigbuild` | Cross-compile using Zig as a universal C/C++ toolchain โ€” no sysroot needed | | `cross` | Cross-compile runner using QEMU inside Docker โ€” full stdlib support | | `cargo-ndk` | Build Android libraries with the NDK | | `cbindgen` | Generate C/C++ headers from Rust code | | `flip-link` | Embedded linker that moves the stack below `.bss` to catch stack overflows | ### WASM | Tool | Purpose | |------|---------| | `wasm-pack` | Build, test, and publish Rust-generated WASM packages | | `wasm-bindgen-cli` | Generate JS/TS bindings for Rust WASM modules | | `wasm-tools` | Low-level WASM binary toolkit โ€” validate, transform, component model | | `trunk` | Rust/WASM bundler for web frontends โ€” live-reload dev server | | `wasm-opt` (binaryen) | WASM binary optimiser โ€” shrinks and speeds up `.wasm` output | ### Docs | Tool | Purpose | |------|---------| | `mdbook` | Build documentation books from Markdown | | `mdbook-toc` | Auto-generate table-of-contents for mdBook chapters | ### Workflow & dev loop | Tool | Purpose | |------|---------| | `bacon` | Background build/test runner โ€” re-runs on file save, stays in terminal | | `cargo-watch` | Re-run any cargo command on file change | | `cargo-edit` | `cargo add`, `cargo rm`, `cargo upgrade` โ€” edit `Cargo.toml` from CLI | | `cargo-update` | Update installed cargo binaries (`cargo install-update -a`) | | `cargo-outdated` | Show outdated `Cargo.toml` dependencies | | `cargo-info` | Detailed crate info from crates.io | | `cargo-msrv` | Find and verify the minimum supported Rust version | ### Compilation cache | Tool | Purpose | |------|---------| | `sccache` | Shared compilation cache โ€” cache on local disk, S3, Redis, GCS, or Azure | ### Database (best-effort) | Tool | Purpose | |------|---------| | `sqlx-cli` | Compile-time SQL verification and migration runner for sqlx | | `sea-orm-cli` | Migration generator and entity scaffolder for SeaORM | Both are built with `rustls` instead of `native-tls` (pure-Rust TLS stack, no OpenSSL dependency) and support postgres, mysql, and sqlite. Projects with unusual feature requirements may `cargo install` them again with different flags. --- ## ๐Ÿ’พ Cache & persistence Four paths are declared as Docker `VOLUME`s: | Volume path | Contents | |-------------|----------| | `/usr/local/share/cargo` | Registry index, downloaded crate tarballs, installed binaries | | `/usr/local/share/rustup` | Toolchains and components | | `/root/.cache/sccache` | Compiled artifact cache (sccache) | | `/config`, `/data` | Container config and data | ### Named volumes (recommended) ```shell docker run --rm -v "$PWD:/app" \ -v rust-cargo:/usr/local/share/cargo \ -v rust-rustup:/usr/local/share/rustup \ -v rust-sccache:/root/.cache/sccache \ casjaysdev/rust:latest ``` ### Share with the host's own Rust installation ```shell docker run --rm -v "$PWD:/app" \ -v ~/.cargo:/usr/local/share/cargo \ -v ~/.rustup:/usr/local/share/rustup \ -v ~/.cache/sccache:/root/.cache/sccache \ casjaysdev/rust:latest ``` ### sccache compilation caching (on by default) `sccache` is installed and **active by default**. `RUSTC_WRAPPER=sccache` is set in `/etc/profile.d/rust.sh` so every login shell automatically routes `rustc` invocations through the cache. `SCCACHE_DIR` points to `/root/.cache/sccache`, which is declared as a Docker volume. ```shell docker run --rm -v "$PWD:/app" \ -v rust-sccache:/root/.cache/sccache \ casjaysdev/rust:latest cargo build --release ``` Cache hits skip recompilation entirely, dramatically speeding up incremental and repeated builds. `CARGO_INCREMENTAL` is forced to `0` because cargo's own incremental compilation conflicts with sccache's shared cache. To opt out: `-e RUSTC_WRAPPER=` #### Remote sccache backends Point sccache at S3, Redis, GCS, or Azure by setting the relevant env vars before the run. The sccache documentation covers the full list; a quick example for S3: ```shell docker run --rm -v "$PWD:/app" \ -e RUSTC_WRAPPER=sccache \ -e SCCACHE_BUCKET=my-bucket \ -e SCCACHE_REGION=us-east-1 \ -e AWS_ACCESS_KEY_ID=... \ -e AWS_SECRET_ACCESS_KEY=... \ casjaysdev/rust:latest ``` ### BuildKit cache mounts (for image builds) The `Dockerfile` uses `--mount=type=cache` across all stages. This keeps the apk index, cargo registry, rustup downloads, and sccache populated between `docker build` runs so rebuilding after a change does not re-download or recompile anything: ```shell # BuildKit is the default since Docker 23; no flags needed docker build --tag casjaysdev/rust:local . ``` | Stage | Cache mount ID | Contents | |-------|----------------|----------| | `build` | `apk-cache-` | Alpine package index and downloaded APKs | | `build` | `rustup-downloads-` | rustup toolchain and component tarballs | | `build` | `sccache-build-` | sccache compiled-artifact cache for the build stage | | `rust-tools` | `cargo-registry-native` | Cargo registry index (for cargo-binstall metadata) | | `rust-tools` | `cargo-git-native` | Cargo git dependencies | `` is `amd64` or `arm64`. Per-arch IDs prevent cross-arch cache corruption in multi-platform builds. --- ## โš™๏ธ Environment variables | Variable | Default | Purpose | |----------|---------|---------| | `CARGO_HOME` | `/usr/local/share/cargo` | Registry, crates, installed cargo binaries | | `RUSTUP_HOME` | `/usr/local/share/rustup` | Toolchains and components | | `RUSTUP_TOOLCHAIN` | `stable` | Default channel | | `SCCACHE_DIR` | `/root/.cache/sccache` | Local sccache storage directory | | `CARGO_INCREMENTAL` | `0` | Disabled โ€” conflicts with sccache shared cache | | `RUSTC_WRAPPER` | `sccache` | Active by default; set to empty string to disable | | `CARGO_WORKDIR` | *(unset)* | Override working directory for `rust-workflow` | | `CARGO_BUILD_TARGET` | *(unset)* | Cross-compile triple for `rust-workflow` | | `TZ` | `America/New_York` | Override at run time with `-e TZ=...` | `CARGO_TARGET_DIR` is intentionally **not** set so each project keeps its own `./target/` directory. Export it yourself if you want a shared build cache across projects. Convenience symlinks so standard tools find their home: | Symlink | Target | |---------|--------| | `/root/.cargo` | `/usr/local/share/cargo` | | `/root/.rustup` | `/usr/local/share/rustup` | --- ## ๐ŸŒ Cross-compile ### Pre-installed targets | Family | Targets | |--------|---------| | Linux musl | `x86_64`, `aarch64`, `i686`, `armv7`, `riscv64gc` | | Linux glibc | `x86_64`, `aarch64`, `i686`, `armv7`, `arm`, `riscv64gc`, `ppc64le`, `s390x` | | Windows GNU | `x86_64-gnu`, `i686-gnu`, `aarch64-gnullvm` | | macOS | `x86_64-apple-darwin`, `aarch64-apple-darwin` | | BSD | `x86_64-unknown-freebsd` | | WASM | `wasm32-unknown-unknown`, `wasm32-wasip1`, `wasm32-wasip2`, `wasm32-unknown-emscripten` | | Embedded ARM | `thumbv6m-none-eabi`, `thumbv7em-none-eabihf`, `thumbv8m.main-none-eabi` | | Embedded RISC-V | `riscv32imc-unknown-none-elf`, `riscv32imac-unknown-none-elf` | | Android | `aarch64-linux-android` | `rustup target add ` to install any additional target at runtime. ### Pure-Rust crates โ€” `cargo build` A pre-configured `$CARGO_HOME/config.toml` maps cross-compile linkers: `rust-lld` for ARM/aarch64/embedded and `*-w64-mingw32-gcc` for Windows GNU. Plain `cargo build --target` works for pure-Rust crates on most targets: ```shell cargo build --release --target aarch64-unknown-linux-musl cargo build --release --target armv7-unknown-linux-musleabihf cargo build --release --target x86_64-pc-windows-gnu cargo build --release --target wasm32-wasip1 ``` ### Crates with C dependencies โ€” `cargo zigbuild` For crates that link against C code (`*-sys`, `openssl-sys`, `ring`, etc.) use `cargo zigbuild`. Zig ships as a universal C/C++ cross-toolchain and handles linking and C compilation without a target sysroot: ```shell cargo zigbuild --release --target riscv64gc-unknown-linux-musl cargo zigbuild --release --target s390x-unknown-linux-gnu cargo zigbuild --release --target x86_64-apple-darwin cargo zigbuild --release --target aarch64-apple-darwin ``` ### Full stdlib cross-compile โ€” `cross` `cross` runs the official cross-rs container for targets that need a complete target-arch libc or runtime: ```shell cross build --release --target powerpc64le-unknown-linux-gnu ``` ### Caveats - **macOS SDK not bundled.** Pure-Rust + `cargo zigbuild` works. Code that calls Apple system frameworks (Cocoa, CoreFoundation, etc.) needs the SDK. - **Windows MSVC ABI** (`*-pc-windows-msvc`) is not supported โ€” use `*-pc-windows-gnu` or `*-pc-windows-gnullvm`. - **Embedded targets** (`thumbv*`, `riscv32*-none-*`) require `no_std` source with a `#[panic_handler]` โ€” a `std` hello-world will not compile for them. --- ## ๐Ÿงช Miri (undefined behavior detection) Miri is installed on the nightly toolchain and detects undefined behavior, incorrect use of unsafe, borrow violations across FFI, and data races in tests: ```shell # run your test suite under miri cargo +nightly miri test # run a specific test cargo +nightly miri test my_test_name # run miri in tree mode for finer control cargo +nightly miri run ``` Miri is slower than a normal test run โ€” use it targeted on unsafe code or after a refactor rather than in the default CI path. --- ## ๐Ÿ› ๏ธ Development ```shell git clone "https://github.com/dockersrc/rust" "$HOME/Projects/github/dockersrc/rust" cd "$HOME/Projects/github/dockersrc/rust" docker build --tag casjaysdev/rust:local . ``` BuildKit is required (default in Docker 23+). Cache mounts keep subsequent builds fast โ€” cargo registry, rustup downloads, and sccache data persist in BuildKit's own cache layer storage. ### Build architecture โ€” native cross-compilation The `Dockerfile` uses the same `--platform=$BUILDPLATFORM` pattern as the Go image's `go-tools` stage. A dedicated `rust-tools` stage runs natively on the build host (always amd64 in CI) and downloads prebuilt tool binaries for the target arch before the main build stage ever starts. This eliminates QEMU emulation entirely for tool installation: | How | What | |-----|------| | `cargo binstall --disable-strategies compile` | Fetches prebuilt binaries from GitHub releases โ€” no compilation, tools without prebuilts are skipped | Tools with C dependencies use pure-Rust alternatives wherever possible: `rustls` instead of `native-tls`/OpenSSL (sqlx-cli, sea-orm-cli, trunk); bundled SQLite via `rusqlite`'s `bundled` feature. **Note:** Some tools may be missing on `linux/arm64` if no prebuilt binary exists for that architecture. Core tools (`just`, `cargo-nextest`, `sccache`, `cargo-audit`, `cargo-deny`, `hyperfine`, `mdbook`, `dprint`, etc.) have arm64 prebuilts; niche tools may be amd64-only. **Expected multi-arch build times:** | Arch | Before (QEMU) | After (prebuilt-only) | |------|---------------|------------------------| | `linux/amd64` | ~20 min | ~10โ€“15 min | | `linux/arm64` | ~15 hours | ~5โ€“15 min | --- ## ๐Ÿ“„ License WTFPL --- ๐Ÿค– [casjay](https://github.com/casjay) โ›ต [casjaysdevdocker](https://github.com/casjaysdevdocker) โ€” [Docker Hub](https://hub.docker.com/r/casjaysdev/rust)