kube
kube copied to clipboard
Document recommended deployment environment
#331 highlights that this can be pretty confusing at the moment...
Arguably this isn't really specific to kube-rs, but at the same time it's probably something that will be relevant for 99% of kube-rs users.
Personally, I'd lean towards crate2nix and buildLayeredImage because:
- It has much better caching behaviour than Dockerfiles (since it caches each Rust package individually, just like Cargo)
- It automatically figures out which dependencies are required at runtime, and tree-shakes the rest
- It can theoretically cross-build packages, but I'm not sure about whether the Rust tooling is set up for this yet
However, it does have some disadvantages...
- Nix doesn't have the mindshare of Dockerfiles
- It can take advantage of remote builders, but it's a bit messier to set up than Docker for Desktop
cargo-wharf is good at caching too.
Oh, that's interesting. The caching seems stronger than for the plain Dockerfile setup, but there doesn't seem to be much of a story for non-cargo build steps (seeing apt invoked in the instructions is a bit worrying..). I'd also be a bit wary about encouraging dependencies on non-official Docker Hub images, given their recent changes to both rate limits and retention.
For what its work I've been using ekidd/rust-musl-builder as my builder.
Here is an example:
FROM ekidd/rust-musl-builder:stable as builder
ENV APP=my-app
RUN mkdir .cargo src
COPY Cargo.toml Cargo.toml
COPY Cargo.lock Cargo.lock
RUN echo "fn main() {println!(\"if you see this, the build broke\")}" > src/lib.rs && \
cargo vendor > .cargo/config && \
cargo build --release && \
rm -rf src
COPY src src
RUN rm -rf target/release/**/libsrc*
RUN cargo build --release
FROM alpine:latest
ARG APP_FOLDER=/usr/src/app
ENV APP_USER=appuser
RUN addgroup -S $APP_USER \
&& adduser -S -g $APP_USER $APP_USER
RUN apk update \
&& apk add --no-cache ca-certificates open-ssl \
&& rm -rf /var/cache/apk/*
COPY --from=builder /home/rust/src/target/x86_64-unknown-linux-musl/release/${APP} ${APP_FOLDER}/${APP}
ENV PATH="${APP_FOLDER}:${PATH}"
CMD ["${APP}"]
Replaced the hacky method with cargo chef
FROM ekidd/rust-musl-builder:stable as planner
RUN cargo install cargo-chef
COPY . .
RUN cargo chef prepare --recipe-path recipe.json
FROM ekidd/rust-musl-builder:stable as cacher
RUN cargo install cargo-chef
COPY --from=planner /home/rust/src/recipe.json recipe.json
RUN cargo chef cook --release --recipe-path recipe.json
FROM ekidd/rust-musl-builder:stable as builder
COPY . .
COPY --from=cacher /home/rust/src/target target
COPY --from=cacher /home/rust/.cargo /home/rust/.cargo
RUN cargo build --release
FROM alpine:latest
ENV APP=my-app
ARG APP_FOLDER=/usr/src/app
ENV APP_USER=appuser
RUN addgroup -S $APP_USER \
&& adduser -S -g $APP_USER $APP_USER
RUN apk update \
&& apk add --no-cache ca-certificates \
&& rm -rf /var/cache/apk/*
COPY --from=builder /home/rust/src/target/x86_64-unknown-linux-musl/release/${APP} ${APP_FOLDER}/${APP}
ENV PATH="${APP_FOLDER}:${PATH}"
CMD ${APP}