Skip to content

Commit

Permalink
feat: smaller docker image (#16)
Browse files Browse the repository at this point in the history
* multistage docker build + cargo chef

* fix(docker): drop unused sh binary

* docker: add labels and better comments

* fix(docker): drop unneeded PATH

* docs(readme): update missing rdfpipe features

* change docker user name

* explicitely allow COPY targets with .dockerignore
  • Loading branch information
cmdoret authored Dec 14, 2023
1 parent 5cd8136 commit 8e7d7a5
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 12 deletions.
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*
!src/
!Cargo.toml
!Cargo.lock
77 changes: 66 additions & 11 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,19 +1,74 @@
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
ARG RUST_BASE=rust:1.74.0-slim-bookworm
ARG RUNNER_BASE=gcr.io/distroless/cc-debian12
ARG VERSION_BUILD=0.1.0

# Add source code under new user
ADD --chown=rust:rust . ./
### 1: Read code and write recipe file
FROM ${RUST_BASE} AS planner
WORKDIR /app
RUN cargo install cargo-chef
COPY . .
RUN cargo chef prepare --recipe-path recipe.json

### 2: Cache compiled dependencies for faster builds
FROM ${RUST_BASE} 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_BASE} AS builder

# Create unprivileged user
ENV USER=appuser
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 ${RUNNER_BASE} AS runner

# Add annotations
LABEL org.opencontainers.image.source=https://github.com/SDSC-ORD/rdfpipe-rs
LABEL org.opencontainers.image.description="Quickly convert between RDF file formats. A rust implementation of rdfpipe based on the sophia crate."
LABEL org.opencontainers.image.licenses=GPL-3.0-or-later
LABEL org.opencontainers.image.version ${VERSION_BUILD}

WORKDIR /app

# Import user files
COPY --from=builder /etc/passwd /etc/passwd
COPY --from=builder /etc/group /etc/group

# 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

# Use unprivileged user
USER appuser:appuser

CMD /usr/local/rdfpipe-rs
ENTRYPOINT ["./rdfpipe-rs"]

1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ rdfpipe-rs is still missing the following features:

* json-ld support
* quad support (named graphs)
* serializing prettified turtle.
* `--ns` option for explicit namespace binding


Expand Down

0 comments on commit 8e7d7a5

Please sign in to comment.