diff --git a/README.md b/README.md index 2cd7e8b..3370bac 100644 --- a/README.md +++ b/README.md @@ -1,137 +1,434 @@ -## ๐Ÿ‘‹ Welcome to rust ๐Ÿš€ +# rust -A Docker image for building Rust projects. Installs the latest stable -Rust toolchain via the official `rustup-init` bootstrapper at image -build time (SHA256-verified from `static.rust-lang.org`) so the image -is never behind upstream. Includes 30 pre-installed cross-compile -targets and a comprehensive set of cargo dev tools, plus the common -build deps (git, make, build-base, clang, lld, mingw-w64, zig, cmake, -perl, openssl-dev, protobuf, jq, binaryen, wabt). +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. -The image is a build environment โ€” it idles after init so you can -`docker exec` into it or use `docker compose exec` for one-off `cargo -build`, `cargo test`, `cargo clippy`, etc. +--- -### What's included - -- **Toolchain components** (via rustup): rustfmt, clippy, rust-src, - rust-analyzer, llvm-tools-preview -- **Workflow**: cargo-binstall, cargo-edit, cargo-watch, cargo-update, - cargo-outdated, cargo-expand, cargo-info, bacon -- **Test / coverage / mutation**: cargo-nextest, cargo-llvm-cov, - cargo-tarpaulin, cargo-mutants -- **QA / audit / policy**: cargo-audit, cargo-deny, cargo-machete, - cargo-msrv, cargo-semver-checks -- **Build / packaging / release**: cargo-make, cargo-deb, cargo-generate, - cargo-release, cargo-dist, cargo-chef, cargo-zigbuild, just -- **Docs**: mdbook, mdbook-toc -- **WASM**: wasm-pack, wasm-bindgen-cli, wasm-tools, trunk -- **Cross / embedded**: cargo-binutils, cargo-cross, flip-link, - probe-rs, cargo-ndk, cbindgen -- **Profiling / inspection**: samply, cargo-bloat, cargo-asm -- **DB migrations / ORMs**: sqlx-cli, sea-orm-cli *(best-effort โ€” - may need manual install with project-specific feature flags)* -- **Misc**: tokei, hyperfine, cargo-flamegraph - - -## Install my system scripts +## ๐Ÿ“ฆ Pull ```shell - sudo bash -c "$(curl -q -LSsf "https://github.com/systemmgr/installer/raw/main/install.sh")" - sudo systemmgr --config && sudo systemmgr install scripts +docker pull casjaysdev/rust:latest ``` - -## Automatic install/update - -```shell -dockermgr update rust + +--- + +## โšก Default behavior + +Running the container with no arguments automatically executes +**`rust-workflow`** โ€” a four-step pipeline against the project mounted at +`/app`: + ``` - -## Install and run container - +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 +``` + +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 +``` + +--- + +## ๐Ÿณ 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 -dockerHome="/var/lib/srv/$USER/docker/casjaysdevdocker/rust/rust/latest/volumes" -mkdir -p "/var/lib/srv/$USER/docker/rust/volumes" -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" \ -casjaysdevdocker/rust:latest + --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 ``` - -## via docker-compose - + +### docker-compose + ```yaml -version: "2" services: - ProjectName: - image: casjaysdevdocker/rust - container_name: casjaysdevdocker-rust + rust: + image: casjaysdev/rust:latest + container_name: casjaysdev-rust + hostname: rust environment: - TZ=America/New_York - - HOSTNAME=rust volumes: - - "/var/lib/srv/$USER/docker/casjaysdevdocker/rust/rust/latest/volumes/data:/data:z" - - "/var/lib/srv/$USER/docker/casjaysdevdocker/rust/rust/latest/volumes/config:/config:z" + - rust-cargo:/usr/local/share/cargo + - rust-rustup:/usr/local/share/rustup + - rust-sccache:/root/.cache/sccache + - .:/app restart: always -``` - -## Usage -The container idles after init. Use `docker exec` (or `docker compose -exec`) to run cargo commands against a project mounted into the -container, or do a one-shot build with `docker run --rm`: - -```shell -# one-off build (mount your project at /app) -docker run --rm -it \ - -v "$PWD:/app" \ - -w /app \ - casjaysdevdocker/rust:latest \ - bash -lc 'cargo build --release' - -# interactive dev shell -docker run --rm -it \ - -v "$PWD:/app" \ - -w /app \ - casjaysdevdocker/rust:latest \ - bash -l - -# exec into the long-running container -docker exec -it casjaysdevdocker-rust-latest bash -l -docker exec casjaysdevdocker-rust-latest cargo test -docker exec casjaysdevdocker-rust-latest cargo clippy --all-targets -docker exec casjaysdevdocker-rust-latest cargo nextest run +volumes: + rust-cargo: + rust-rustup: + rust-sccache: ``` -`WORKDIR` inside the image is `/app`. Project code can also be mounted -at `/work`, `/root/app`, `/root/project`, or `/data/build` โ€” all are -created on startup. +--- -## Cross-compile +## ๐Ÿ”ง Included tools -A pre-configured `$CARGO_HOME/config.toml` ships with the image. It -points cross-compile linkers at `rust-lld` (for ARM/aarch64/embedded) -or `*-w64-mingw32-gcc` (for Windows GNU), so plain `cargo build ---target=...` works for **pure-Rust** crates against most targets out -of the box: +### 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 | +| `cargo-flamegraph` | Generate flame graphs from `cargo bench` or any cargo command | + +### 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 | + +### 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 `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 -cargo build --release --target aarch64-unknown-linux-musl # rust-lld +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 +``` + +### 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`: + +```shell +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: + +```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` 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: + +```shell +# 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 ` 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 # mingw +cargo build --release --target x86_64-pc-windows-gnu cargo build --release --target wasm32-wasip1 ``` -For crates with C deps (`*-sys`, openssl-sys, ring, etc.) or targets -that need a target-arch libc, use `cargo zigbuild` โ€” it bundles Zig as -a universal C cross-toolchain and handles both linking and C compilation: +### 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 @@ -140,101 +437,95 @@ cargo zigbuild --release --target x86_64-apple-darwin cargo zigbuild --release --target aarch64-apple-darwin ``` -Run `rustup target list --installed` inside the container for the full -target list, or `rustup target add ` to grab anything else. +### Full stdlib cross-compile โ€” `cross` -### Pre-installed targets +`cross` runs the official cross-rs container for targets that need a complete +target-arch libc or runtime: -| Family | Targets | -|---|---| -| Linux musl | x86_64, aarch64, i686, armv7, riscv64gc | -| Linux glibc | x86_64, aarch64, i686, armv7, arm, riscv64gc, ppc64le, s390x | -| Windows | x86_64-gnu, i686-gnu, aarch64-gnullvm | -| macOS | x86_64, aarch64 | -| BSD | x86_64-freebsd | -| WASM | wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2, wasm32-emscripten | -| Embedded ARM | thumbv6m, thumbv7em, thumbv8m.main | -| Embedded RISC-V | riscv32imc, riscv32imac | -| Android | aarch64-linux-android | +```shell +cross build --release --target powerpc64le-unknown-linux-gnu +``` ### Caveats -- **macOS SDK is not bundled.** Pure-Rust + `cargo zigbuild` builds for - `*-apple-darwin` work without it. Code that calls into Apple system - frameworks (Cocoa, CoreFoundation, etc.) needs the SDK separately. -- **Windows MSVC ABI** (`*-pc-windows-msvc`) is not supported. Use - `*-pc-windows-gnu` or `*-pc-windows-gnullvm` instead. -- **Embedded targets** (`thumbv*`, `riscv32*-none-*`) require `no_std` - source code with a `#[panic_handler]` โ€” a `std` hello-world won't - compile for them. +- **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. -## Environment variables +--- -| Var | Default | Purpose | -|--------------------|-------------------------------|------------------------------------------| -| `CARGO_HOME` | `/usr/local/share/cargo` | Registry, crates, installed cargo bins | -| `RUSTUP_HOME` | `/usr/local/share/rustup` | Toolchains and components | -| `RUSTUP_TOOLCHAIN` | `stable` | Default channel | -| `TZ` | `America/New_York` | Override at run time (`-e TZ=...`) | +## ๐Ÿงช Miri (undefined behavior detection) -`CARGO_TARGET_DIR` is intentionally **not** set so each project keeps -its own `./target/` (standard cargo behavior). Export it yourself if -you want a shared cache across projects. - -## Persistence - -Rust state lives at two canonical FHS paths, both declared as Docker -`VOLUME`s: - -- **`/usr/local/share/cargo`** โ€” registry index, downloaded crates, - user-installed cargo binaries -- **`/usr/local/share/rustup`** โ€” toolchains and components - -Mount named volumes so they survive container rebuilds โ€” saves -bandwidth and dramatically speeds up subsequent builds: +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 -# named volumes (managed by docker, recommended) -docker run \ +# 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 + +```shell +dockermgr update rust +``` + +Or manually: + +```shell +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 \ - ... - -# or share with the host's own Rust state (bind mounts) -docker run \ - -v ~/.cargo:/usr/local/share/cargo \ - -v ~/.rustup:/usr/local/share/rustup \ - ... + -v rust-sccache:/root/.cache/sccache \ + casjaysdev/rust:latest ``` -For convenience these all resolve to the canonical dirs via symlinks: +--- -- `/root/.cargo` โ†’ `/usr/local/share/cargo` (default rustup location) -- `/root/.rustup` โ†’ `/usr/local/share/rustup` -- `/data/cargo` โ†’ `/usr/local/share/cargo` (created at container start) -- `/data/rustup` โ†’ `/usr/local/share/rustup` (created at container start) +## ๐Ÿ› ๏ธ Build the image locally - -## Get source files - ```shell -dockermgr download src casjaysdevdocker/rust +git clone "https://github.com/dockersrc/rust" "$HOME/Projects/github/dockersrc/rust" +cd "$HOME/Projects/github/dockersrc/rust" +docker build --tag casjaysdev/rust:local . ``` - -OR - -```shell -git clone "https://github.com/casjaysdevdocker/rust" "$HOME/Projects/github/casjaysdevdocker/rust" -``` - -## Build container - -```shell -cd "$HOME/Projects/github/casjaysdevdocker/rust" -buildx -``` - -## Authors - -๐Ÿค– casjay: [Github](https://github.com/casjay) ๐Ÿค– -โ›ต casjaysdevdocker: [Github](https://github.com/casjaysdevdocker) [Docker](https://hub.docker.com/u/casjaysdevdocker) โ›ต + +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](https://github.com/casjay) +โ›ต [casjaysdevdocker](https://github.com/casjaysdevdocker) โ€” [Docker Hub](https://hub.docker.com/u/casjaysdevdocker)