From 9af7964a9d43d5f01c05326b996936f13647a561 Mon Sep 17 00:00:00 2001 From: cmdoret Date: Thu, 23 Nov 2023 21:27:00 +0100 Subject: [PATCH] multistage docker build + cargo chef --- Dockerfile | 68 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 11 deletions(-) diff --git a/Dockerfile b/Dockerfile index 33e16ce..8f2cc69 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,19 +1,65 @@ -ARG BASE_IMAGE=ekidd/rust-musl-builder:latest +# This Dockerfile uses a multi-stage build with +# cargo-chef to cache compiled dependencies and +# minimize the size of the final image. -# Build environment -FROM ${BASE_IMAGE} AS builder +# 1: Read code and write recipe file +FROM rust AS planner +WORKDIR /app +RUN cargo install cargo-chef +COPY . . +RUN cargo chef prepare --recipe-path recipe.json -# Add source code under new user -ADD --chown=rust:rust . ./ +# 2: Cache compiled dependencies for faster builds +FROM rust AS cacher +WORKDIR /app +RUN cargo install cargo-chef +COPY --from=planner /app/recipe.json recipe.json +RUN cargo chef cook --release --recipe-path recipe.json + + +# 3: Build project, but reuse cached dependencies +FROM rust AS builder + +# Create unprivileged user +ENV USER=rust +ENV UID=1001 + +RUN adduser \ + --disabled-password \ + --gecos "" \ + --home "/nonexistent" \ + --shell "/sbin/nologin" \ + --no-create-home \ + --uid "${UID}" \ + "${USER}" + +COPY . /app +WORKDIR /app + +# Copy pre-built dependencies +COPY --from=cacher /app/target target +COPY --from=cacher /usr/local/cargo /usr/local/cargo RUN cargo build --release -# Runner image -FROM alpine:latest -RUN apk --no-cache add ca-certificates + +# 4: Copy required binaries into distroless runner +FROM gcr.io/distroless/cc-debian12 AS runner + +WORKDIR /app + +# Import user files +COPY --from=builder /etc/passwd /etc/passwd +COPY --from=builder /etc/group /etc/group +COPY --from=builder /bin/sh /bin/sh + +# Import binary COPY --from=builder \ - /home/rust/src/target/x86_64-unknown-linux-musl/release/rdfpipe-rs \ - /usr/local/bin/ + /app/target/release/rdfpipe-rs \ + /app/rdfpipe-rs + +USER rust:rust -CMD /usr/local/rdfpipe-rs +ENV PATH="/app/:${PATH}" +ENTRYPOINT ["rdfpipe-rs"]