Skip to content

Instantly share code, notes, and snippets.

@ihrwein
Last active September 26, 2021 16:59
Show Gist options
  • Save ihrwein/1f11efc568601055f2c78eb471a41d99 to your computer and use it in GitHub Desktop.
Save ihrwein/1f11efc568601055f2c78eb471a41d99 to your computer and use it in GitHub Desktop.
Building minimal Rust containers with Docker multi stage builds

The built image for a hello world project is less than 8 MB.

Builder image (it'd be best to upload this image to Docker Hub. This is 100% percent reusable).

FROM ubuntu:latest

ENV TARGET=x86_64-unknown-linux-musl
ENV BUILD_DIR=/src/target/x86_64-unknown-linux-musl/release/

RUN apt-get update && \
    apt-get install \
        curl \
        gcc \
        -y

RUN curl https://sh.rustup.rs -sSf -o /tmp/rustup-init.sh
RUN sh /tmp/rustup-init.sh -y

RUN ~/.cargo/bin/rustup target add ${TARGET}

ONBUILD COPY . /src
ONBUILD WORKDIR /src

ONBUILD RUN ~/.cargo/bin/cargo test --release --target=${TARGET}
ONBUILD RUN ~/.cargo/bin/cargo build --release --target=${TARGET}

# Build artifacts will be available in /app.
RUN mkdir /app
# Copy the "interesting" files into /app.
ONBUILD RUN find ${BUILD_DIR} \
                -regextype egrep \
                # The interesting binaries are all directly in ${BUILD_DIR}.
                -maxdepth 1 \
                # Well, binaries are executable.
                -executable \
                # Well, binaries are files.
                -type f \
                # Filter out tests.
                ! -regex ".*\-[a-fA-F0-9]{16,16}$" \
                # Copy the matching files into /app.
                -exec cp {} /app \;

ONBUILD RUN echo "The following files will be copied to the runtime image: $(ls /app)"

Build it once with docker build . -t rust:stable.

Runtime image (create this Dockerfile in your crate, next to Cargo.toml):

FROM rust:stable

FROM alpine:latest
COPY --from=0 /app/ /app/

CMD ["/app/hello2"]

That's the minimal amount of boilerplate that currently works.

@howinator
Copy link

Are you not using this image for the base image just because it was very new when you first wrote the gist?

@Gisleburt
Copy link

You can name your build steps.

FROM rust:stable as builder

FROM alpine:latest
COPY --from=builder /app/ /app/

CMD ["/app/hello2"]

I also recommend looking ekidd/rust-musl-builder which will help with static linking

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment