Compiling rust dependencies every time a docker image is built can take a very long time. To cache dependencies so that they don’t need to be compiled every time, you can use/abuse how docker caching works using stages.
The following example uses two stages to build and then run my_app
. By generating a fake main.rs
and compiling it, Docker is tricked into caching all dependencies. We then bust the cache to trigger building the app by copying the actual app code and touch
-ing main.rs
.
# Build stage
FROM rust:bookworm AS builder
WORKDIR /
## Cache rust dependencies
RUN mkdir ./src && echo 'fn main() { println!("Dummy!"); }' > ./src/main.rs
COPY ./Cargo.toml .
RUN cargo build --release
## Actually build the app
RUN rm -rf ./src
COPY ./src ./src
RUN touch -a -m ./src/main.rs
RUN cargo build --release
# Run stage
FROM debian:bookworm-slim AS runner
COPY --from=builder /target/release/my_app /my_app
ENTRYPOINT ["./my_app"]
I adapted this from the StackOverflow thread here.
See also:
- This works particularly well when running dokku on aws when the app uses a
Dockerfile
- Coming back to rust after 4 years