Quantcast
Viewing all articles
Browse latest Browse all 44

Answer by Mark for Cache Cargo dependencies in a Docker volume

Here's an overview of the possibilities. (Scroll down for my original answer.)

  • Add Cargo files, create fake main.rs/lib.rs, then compile dependencies. Afterwards remove the fake source and add the real ones. [Caches dependencies, but several fake files with workspaces].
  • Add Cargo files, create fake main.rs/lib.rs, then compile dependencies. Afterwards create a new layer with the dependencies and continue from there. [Similar to above].
  • Externally mount a volume for the cache dir. [Caches everything, relies on caller to pass --mount].
  • Use RUN --mount=type=cache,target=/the/path cargo build in the Dockerfile in new Docker versions. [Caches everything, seems like a good way, but currently too new to work for me. Executable not part of image. Edit: See here for a solution.]
  • Run sccache in another container or on the host, then connect to that during the build process. See this comment in Cargo issue 2644.
  • Use cargo-build-deps. [Might work for some, but does not support Cargo workspaces (in 2019)].
  • Wait for Cargo issue 2644. [There's willingness to add this to Cargo, but no concrete solution yet].
  • Using VOLUME ["/the/path"] in the Dockerfile does NOT work, this is per-layer (per command) only.

Note: one can set CARGO_HOME and ENV CARGO_TARGET_DIR in the Dockerfile to control where download cache and compiled output goes.

Also note: cargo fetch can at least cache downloading of dependencies, although not compiling.

Cargo workspaces suffer from having to manually add each Cargo file, and for some solutions, having to generate a dozen fake main.rs/lib.rs. For projects with a single Cargo file, the solutions work better.


I've got caching to work for my particular case by adding

ENV CARGO_HOME /code/dockerout/cargoENV CARGO_TARGET_DIR /code/dockerout/target

Where /code is the directory where I mount my code.

This is externally mounted, not from the Dockerfile.

EDIT1: I was confused why this worked, but @b.enoit.be and @BMitch cleared up that it's because volumes declared inside the Dockerfile only live for one layer (one command).


Viewing all articles
Browse latest Browse all 44

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>