DEV Community

Justin Poehnelt
Justin Poehnelt

Posted on • Originally published at justin.poehnelt.com on

Optimized Dockerfile for Rust

Below is a simple Dockerfile for a Rust project. It uses a multi-stage build to first build the project and then copy the binary into a new image. This is a common pattern for compiled languages.

The first stage is named builder. It caches the dependencies with a dummy src/main.rs file. This allows the dependencies to be cached and reused when the source code changes.

# Build dependencies
COPY Cargo.toml Cargo.lock ./
RUN mkdir ./src && echo 'fn main() {}' > ./src/main.rs
RUN cargo build --release
Enter fullscreen mode Exit fullscreen mode

The main.rs file is then deleted and the real source code is copied in. This forces the build to recompile the source code, but not the dependencies.

# Replace with real src
RUN rm -rf ./src
COPY ./src ./src
# break the Cargo cache
RUN touch ./src/main.rs
# Build the project
RUN cargo build --release
Enter fullscreen mode Exit fullscreen mode

The run stage uses the debian:bookworm-slim image which is a minimal Debian image. The bookworm tag is the codename for the next Debian release. The -slim tag is a minimal version of the image.

# Run stage
FROM debian:bookworm-slim as run
RUN apt-get update && apt install -y openssl && rm -rf /var/lib/apt/lists/* && apt-get clean
COPY --from=builder /usr/src/app/target/release/app /usr/local/bin
ENTRYPOINT ["/usr/local/bin/app"]
Enter fullscreen mode Exit fullscreen mode

The full Dockerfile is below.

# Build stage
FROM rust:bookworm as builder
WORKDIR /usr/src/app
# Build dependencies
COPY Cargo.toml Cargo.lock ./
RUN mkdir ./src && echo 'fn main() {}' > ./src/main.rs
RUN cargo build --release
# Replace with real src
RUN rm -rf ./src
COPY ./src ./src
# break the Cargo cache
RUN touch ./src/main.rs
# Build the project
RUN cargo build --release
# Run stage
FROM debian:bookworm-slim as run
RUN apt-get update && apt install -y openssl && rm -rf /var/lib/apt/lists/* && apt-get clean
COPY --from=builder /usr/src/app/target/release/app /usr/local/bin
ENTRYPOINT ["/usr/local/bin/app"]
Enter fullscreen mode Exit fullscreen mode

Top comments (0)