From 7988da620d7dca690fc25dcbf5e21a295211c304 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Jul 2026 18:10:36 +0000 Subject: [PATCH] Docker: copy vendor/ and pin rustc 1.95.0 Two bugs, both pre-existing, the second hidden behind the first. 1. vendor/ was never copied The root manifest has `[patch.crates-io] chacha20 = { path = "vendor/chacha20" }`, and both Dockerfiles do a selective COPY -- Cargo.toml, crates/, src/, examples/, benches/ -- that never included vendor/. Cargo resolves patch entries while LOADING THE MANIFEST, before features and before target selection, so this is not a link-time miss; the build dies at parse: error: failed to load source for dependency `chacha20` Caused by: Unable to update /app/vendor/chacha20 Caused by: failed to read `/app/vendor/chacha20/Cargo.toml` vendor/chacha20 is tracked (18 files) and not gitignored, and .dockerignore does not exclude vendor/ -- the directory simply was never listed. The patch arrived in 2539cad without the Dockerfiles being updated alongside it. Same failure class as the examples/benches note already in the file, which exists because this happened once before. 2. The image pinned rustc 1.94.0 for a crate that requires 1.95 Cargo.toml says `rust-version = "1.95"` and rust-toolchain.toml says channel = "1.95.0", but the Dockerfiles installed 1.94.0 and asserted it. This would have been the very next failure after fixing (1) and was invisible until then. rust-toolchain.toml is deliberately not copied into the image -- rustup would fetch a second toolchain at build time -- so the Dockerfile pin is the only thing keeping the image in step with the repo, and there is now a comment saying so and telling the next person to bump it when the toolchain moves. Verified by reproducing the Docker context exactly (no daemon available): a directory populated with precisely the Dockerfile's COPY list. before, old COPY set: cargo metadata -> exit 101, the identical error after, with vendor/: cargo metadata -> exit 0 then all three of the Dockerfile's RUN steps, on 1.95.0, with the image's RUSTFLAGS="-C target-cpu=x86-64-v3": cargo build --release Finished, 43.21s cargo build --release --features jit-native Finished, 45.99s cargo test --release --lib -- hpc:: 1732 passed, 0 failed Not verified: an actual `docker build`. No daemon in this environment. The simulation reproduces the reported failure byte-for-byte and clears it, and it exercises every RUN line, but it does not cover anything specific to the debian base image or the apt layer. Claude-Session: https://claude.ai/code/session_01VdfbkUCBbtZhy3yjSfCDHp --- Dockerfile | 23 ++++++++++++++++++----- Dockerfile.avx512 | 12 +++++++++--- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index 5e8f1788..32451500 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # ndarray — Railway compile-test image (AVX2 default) # Verifies the HPC module builds cleanly (default + jit-native features) -# Requires Rust 1.94.0 (LazyLock, simd_caps, modern std APIs) +# Requires Rust 1.95.0 (LazyLock, simd_caps, modern std APIs) # # CPU detection & SIMD dispatch documentation: see Dockerfile.md # AVX-512 pinned variant: see Dockerfile.avx512 @@ -15,13 +15,17 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ curl ca-certificates gcc libc6-dev pkg-config libssl-dev \ && rm -rf /var/lib/apt/lists/* -# Install Rust 1.94.0 via rustup +# Install Rust 1.95.0 via rustup — MUST match rust-toolchain.toml (channel = +# "1.95.0") and Cargo.toml's `rust-version = "1.95"`. rust-toolchain.toml is +# deliberately NOT copied into the image (rustup would try to download a second +# toolchain at build time), so this pin is the only thing keeping the image in +# step with the repo — bump it whenever rust-toolchain.toml moves. ENV RUSTUP_HOME=/usr/local/rustup \ CARGO_HOME=/usr/local/cargo \ PATH=/usr/local/cargo/bin:$PATH RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \ - sh -s -- -y --default-toolchain 1.94.0 --profile minimal \ - && rustc --version | grep -q "1.94.0" + sh -s -- -y --default-toolchain 1.95.0 --profile minimal \ + && rustc --version | grep -q "1.95.0" WORKDIR /app @@ -30,6 +34,15 @@ COPY Cargo.toml Cargo.lock ./ COPY ndarray-rand/Cargo.toml ndarray-rand/Cargo.toml COPY crates/ crates/ +# The root Cargo.toml has `[patch.crates-io] chacha20 = { path = "vendor/chacha20" }`. +# Cargo resolves patch entries while LOADING THE MANIFEST — before features, before +# targets, on every command — so without this the build dies at parse with +# "failed to load source for dependency `chacha20` / unable to update +# /app/vendor/chacha20". Same class as the examples/benches note below, and the +# reason a selective-COPY Dockerfile has to be updated whenever a path source is +# added to the manifest. +COPY vendor/ vendor/ + # Copy source COPY src/ src/ COPY ndarray-rand/src/ ndarray-rand/src/ @@ -63,4 +76,4 @@ RUN cargo test --release --lib -- hpc:: 2>&1 && echo "=== HPC TESTS OK ===" # Minimal runtime image — just proves it compiled FROM debian:bookworm-slim COPY --from=builder /app/target/release/libndarray.rlib /usr/local/lib/ -CMD ["echo", "ndarray build verified — Rust 1.94.0"] +CMD ["echo", "ndarray build verified — Rust 1.95.0"] diff --git a/Dockerfile.avx512 b/Dockerfile.avx512 index b1ebe529..33a779ff 100644 --- a/Dockerfile.avx512 +++ b/Dockerfile.avx512 @@ -21,14 +21,20 @@ ENV RUSTUP_HOME=/usr/local/rustup \ CARGO_HOME=/usr/local/cargo \ PATH=/usr/local/cargo/bin:$PATH RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \ - sh -s -- -y --default-toolchain 1.94.0 --profile minimal \ - && rustc --version | grep -q "1.94.0" + sh -s -- -y --default-toolchain 1.95.0 --profile minimal \ + && rustc --version | grep -q "1.95.0" WORKDIR /app COPY Cargo.toml Cargo.lock ./ COPY ndarray-rand/Cargo.toml ndarray-rand/Cargo.toml COPY crates/ crates/ + +# `[patch.crates-io] chacha20 = { path = "vendor/chacha20" }` in the root +# manifest. Cargo resolves patch entries at MANIFEST LOAD, so omitting this +# fails the build at parse, not at link. See the same note in ./Dockerfile. +COPY vendor/ vendor/ + COPY src/ src/ COPY ndarray-rand/src/ ndarray-rand/src/ @@ -51,4 +57,4 @@ RUN cargo test --release --lib -- hpc:: 2>&1 && echo "=== AVX-512 HPC TESTS OK = FROM debian:bookworm-slim COPY --from=builder /app/target/release/libndarray.rlib /usr/local/lib/ -CMD ["echo", "ndarray AVX-512 build verified — Rust 1.94.0, target-cpu=x86-64-v4"] +CMD ["echo", "ndarray AVX-512 build verified — Rust 1.95.0, target-cpu=x86-64-v4"]