FROM rust:1.96-slim-trixie AS chef RUN apt-get update && apt-get install -y --no-install-recommends \ ca-certificates pkg-config perl make cmake clang mold git \ && rm -rf /var/lib/apt/lists/* ENV RUSTFLAGS="-C linker=clang -C link-arg=-fuse-ld=mold" # cargo's own git fetch waits forever on a stalled knot; the cli gives up after # 30s under 1KiB/s and cargo retries it ENV CARGO_NET_GIT_FETCH_WITH_CLI=true \ CARGO_NET_RETRY=5 \ GIT_HTTP_LOW_SPEED_LIMIT=1024 \ GIT_HTTP_LOW_SPEED_TIME=30 RUN rustup toolchain install 1.96.0 \ --profile minimal \ --component rustfmt \ --component clippy \ --target wasm32-unknown-unknown \ --no-self-update ENV CC=clang ENV CXX=clang++ RUN cargo install cargo-chef --version 0.1.78 --locked WORKDIR /src FROM chef AS source COPY Cargo.toml Cargo.lock rust-toolchain.toml ./ COPY lexicons ./lexicons COPY crates ./crates COPY bobbin ./bobbin # keep image lighter by not copying in shuttle, gitmirror, knot2 # does however need some cargo toml patchings RUN sed -i \ -e 's/, "shuttle"//' \ -e 's/, "gitmirror\/crates\/\*"//' \ -e 's/, "knot2\/crates\/\*"//' \ -e '/^knot-[a-z0-9-]* = { path = "knot2\/crates\//d' \ -e '/^gitmirror-[a-z0-9-]* = { path = "gitmirror\/crates\//d' \ -e '/^gix-pack = { path = "knot2\/third_party\/gix-pack" }/d' \ Cargo.toml # the recipe only changes with manifests and the lockfile, so a source-only # change reuses the cooked dependency layer FROM source AS planner RUN cargo chef prepare --recipe-path recipe.json # one "name url rev" line per git source, so fetching them caches on the pins alone RUN awk -F'"' '/^name = /{n=$2} /^source = "git\+/{split($2, s, /[?#]/); sub(/^git\+/, "", s[1]); sub(/^rev=/, "", s[2]); print n, s[1], s[2]}' Cargo.lock \ | sort -u -k2,3 | sort -u -k2,2 > git-deps.txt # the git dependencies come from a knot that is sometimes slow, so they get a # layer that only a pin change invalidates FROM chef AS git-deps COPY --from=planner /src/git-deps.txt ./ RUN mkdir -p /tmp/git-deps/src && touch /tmp/git-deps/src/lib.rs \ && { printf '[package]\nname = "git-deps"\nversion = "0.0.0"\nedition = "2021"\n\n[dependencies]\n'; \ awk '{ printf "%s = { git = \"%s\", rev = \"%s\" }\n", $1, $2, $3 }' git-deps.txt; } > /tmp/git-deps/Cargo.toml \ && cargo fetch --manifest-path /tmp/git-deps/Cargo.toml \ && rm -rf /tmp/git-deps FROM chef AS builder ARG BOBBIN_PROFILE=release COPY --from=git-deps /usr/local/cargo/git /usr/local/cargo/git COPY --from=planner /src/recipe.json recipe.json COPY rust-toolchain.toml ./ RUN cargo chef cook --profile ${BOBBIN_PROFILE} --recipe-path recipe.json --bin bobbin --package bobbin COPY --from=source /src . RUN cargo build --profile ${BOBBIN_PROFILE} --bin bobbin --package bobbin RUN if [ "${BOBBIN_PROFILE}" = "release" ]; then strip target/${BOBBIN_PROFILE}/bobbin; fi FROM debian:trixie-slim ARG BOBBIN_PROFILE=release RUN apt-get update && apt-get install -y --no-install-recommends \ ca-certificates \ && rm -rf /var/lib/apt/lists/* COPY --from=builder /src/target/${BOBBIN_PROFILE}/bobbin /usr/local/bin/bobbin ENV BOBBIN_BIND=0.0.0.0:8090 EXPOSE 8090 ENTRYPOINT ["/usr/local/bin/bobbin"]