Files
rust/README.md
T
jason d917070c1a 🗃️ Could you paste the actual diff content? 🗃️
Could you paste the actual diff content?

Dockerfile
README.md
2026-05-31 23:21:21 -04:00

18 KiB

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

docker pull casjaysdev/rust:latest

Default behavior

Running the container with no arguments automatically executes rust-workflow — a four-step pipeline against the project mounted at /app:

fmt check  →  clippy -D warnings  →  cargo test --all  →  cargo build --release
# run the full workflow against your project
docker run --rm -it \
  -v "$PWD:/app" \
  casjaysdev/rust:latest

Override the working directory with CARGO_WORKDIR, or target a specific cross-compile triple with CARGO_BUILD_TARGET:

docker run --rm -it \
  -v "$PWD:/app" \
  -e CARGO_BUILD_TARGET=aarch64-unknown-linux-musl \
  casjaysdev/rust:latest

🐳 Docker

Quick one-shot commands

# 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

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

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 <target>

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

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

These are installed with broadly compatible feature flags. Projects with unusual feature requirements may need to cargo install them again with project-specific flags.


💾 Cache & persistence

Four paths are declared as Docker VOLUMEs:

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
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

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

Enable sccache compilation caching

sccache is installed and SCCACHE_DIR is pre-configured to /root/.cache/sccache. It is not activated by default. Opt in per run with -e RUSTC_WRAPPER=sccache:

docker run --rm -v "$PWD:/app" \
  -v rust-sccache:/root/.cache/sccache \
  -e RUSTC_WRAPPER=sccache \
  casjaysdev/rust:latest

With RUSTC_WRAPPER=sccache, sccache intercepts every rustc invocation and serves cached object files on cache hits, 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.

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:

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 on both the package install and toolchain install steps. This keeps the apk index, cargo registry, rustup downloads, and sccache populated between docker build runs so rebuilding the image after a change does not re-download anything:

# BuildKit is the default since Docker 23; no flags needed
docker build --tag casjaysdev/rust:local .

Cache mount IDs: apk-cache, cargo-registry, cargo-git, rustup-downloads, sccache-build.


⚙️ 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 — required when using sccache
RUSTC_WRAPPER (unset) Set to sccache to activate compilation caching
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-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 <triple> 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:

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:

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:

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:

# 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.


🚀 Install and run container

dockermgr update rust

Or manually:

dockerHome="/var/lib/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

🛠️ Build the image locally

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 — the cargo registry, rustup downloads, and sccache data persist in BuildKit's own cache layer storage.


📄 License

WTFPL


🤖 casjay
casjaysdevdockerDocker Hub