Can't bind-mount /usr/local/cargo in Rust's Docker image


It’s very useful to have official Docker images with Rust for server-side builds and the like. For whatever reasons, people may also prefer Docker to rustup for managing their local Rust toolchain installations and build crates by bind-mounting the source directory into the container and invoking cargo inside. However, currently both of these use cases are fraught with trial and error when one wants to eliminate repetitive downloads of Cargo registry and dependencies: each container run creates a fresh image, and after the run any downloaded files inside /usr/local/cargo cannot escape the container image and are typically removed together with it. A simple solution would be to mount something like $HOME/.cargo at host as /usr/local/cargo, but in the Rust images (and in general) $CARGO_HOME is also where the toolchain binaries get installed by rustup. So, everyone seems to need to do an intricate mount dance inside /usr/local/cargo, like this. My docker-rust issue about this got closed with the resolution to search for a fix in rustup, but I think a simple Dockerfile fix like moving away all the non-cache files and directories immediately under /usr/local/cargo to where the PATH executable search, linker, etc. will also find the needed files, and replacing them with symlinks to the new locations would do the job. Opinions?


Oh, and it looks like one cannot easily use cargo login/cargo publish, all because the container uses $CARGO_HOME as an easy dump bag for everything. It should be possible to make do with Docker-managed volumes, but these have to be managed per-user (and even per-effective-group, if you’re diligent), and this creates another odd place for sensitive user data like the login token to be left forgotten in.


For those unwilling to wait for a proper fix in rustup (or, better yet, do it and contribute), I have set up an automated build with the quick fix.