# syntax=docker/dockerfile:1 # --------------------------------------------------------------------------- # Multi-service Rust workspace Dockerfile. # # All Rust binaries are compiled in a single builder stage so that shared # dependencies (move-compiler, iota-sdk, identity_iota) compile exactly once. # Previously, building 9 images in parallel caused each image to compile # move-compiler simultaneously, exhausting Docker Desktop's VM RAM. # # docker-compose.yml selects the per-service runtime stage via `target:`. # --------------------------------------------------------------------------- # ---- cargo-chef installer -------------------------------------------------- FROM rust:1.88-slim-bookworm AS chef-installer RUN cargo install cargo-chef --locked # ---- Shared builder base --------------------------------------------------- FROM rust:1.88-slim-bookworm AS base COPY --from=chef-installer /usr/local/cargo/bin/cargo-chef /usr/local/cargo/bin/cargo-chef # Use system git to avoid libgit2 SSL failures inside Docker. ENV CARGO_NET_GIT_FETCH_WITH_CLI=true RUN apt-get update && apt-get install -y --no-install-recommends \ pkg-config libssl-dev git curl \ && rm -rf /var/lib/apt/lists/* # Prevent GnuTLS truncation on large git packs (identity.git, iota.git). RUN git config --global http.postBuffer 524288000 \ && git config --global http.lowSpeedLimit 0 \ && git config --global http.lowSpeedTime 999999 WORKDIR /build # ---- Planner: generate recipe.json from Cargo.lock ------------------------- FROM base AS planner COPY Cargo.toml Cargo.lock ./ COPY .cargo ./.cargo COPY crates ./crates COPY services ./services COPY cli ./cli RUN cargo chef prepare --recipe-path recipe.json # ---- Builder: compile all binaries in one pass ----------------------------- FROM base AS builder # CARGO_BUILD_JOBS=2: limits inter-crate parallelism. # codegen-units=1 (set in [profile.docker]): keeps LLVM single-threaded per crate. ENV CARGO_BUILD_JOBS=2 # ── Dependency layer (cached until Cargo.toml / Cargo.lock changes) ───────── COPY --from=planner /build/recipe.json recipe.json RUN --mount=type=cache,target=/usr/local/cargo/registry \ --mount=type=cache,target=/usr/local/cargo/git \ --mount=type=cache,id=guardian-build-target,target=/build/target \ cargo chef cook --profile docker --recipe-path recipe.json # ── Application layer (invalidated when workspace source changes) ──────────── COPY Cargo.toml Cargo.lock ./ COPY .cargo ./.cargo COPY crates ./crates COPY services ./services COPY cli ./cli # Build ALL service binaries in one cargo invocation. # move-compiler and iota-sdk compile exactly once — not once per service image. RUN --mount=type=cache,target=/usr/local/cargo/registry \ --mount=type=cache,target=/usr/local/cargo/git \ --mount=type=cache,id=guardian-build-target,target=/build/target \ cargo build --profile docker \ --bin cvs \ --bin x402 \ --bin super-certifier-admin \ --bin certifier-service \ --bin registration-app \ --bin guardian \ --bin demo-origin \ && mkdir /out \ && cp target/docker/cvs /out/ \ && cp target/docker/x402 /out/ \ && cp target/docker/super-certifier-admin /out/ \ && cp target/docker/certifier-service /out/ \ && cp target/docker/registration-app /out/ \ && cp target/docker/guardian /out/ \ && cp target/docker/demo-origin /out/ # ---- Runtime base ---------------------------------------------------------- FROM debian:bookworm-slim AS runtime-base RUN apt-get update && apt-get install -y --no-install-recommends \ ca-certificates curl \ && rm -rf /var/lib/apt/lists/* WORKDIR /app # ---- Per-service runtime images -------------------------------------------- # docker-compose.yml references each stage by name via `target:`. FROM runtime-base AS cvs COPY --from=builder /out/cvs /usr/local/bin/cvs ENTRYPOINT ["/usr/local/bin/cvs"] FROM runtime-base AS x402 COPY --from=builder /out/x402 /usr/local/bin/x402 ENTRYPOINT ["/usr/local/bin/x402"] FROM runtime-base AS super-certifier-admin COPY --from=builder /out/super-certifier-admin /usr/local/bin/super-certifier-admin ENTRYPOINT ["/usr/local/bin/super-certifier-admin"] FROM runtime-base AS certifier-service COPY --from=builder /out/certifier-service /usr/local/bin/certifier-service ENTRYPOINT ["/usr/local/bin/certifier-service"] FROM runtime-base AS registration-app COPY --from=builder /out/registration-app /usr/local/bin/registration-app ENTRYPOINT ["/usr/local/bin/registration-app"] FROM runtime-base AS guardian COPY --from=builder /out/guardian /usr/local/bin/guardian ENTRYPOINT ["/usr/local/bin/guardian"] FROM runtime-base AS demo-origin COPY --from=builder /out/demo-origin /usr/local/bin/demo-origin ENTRYPOINT ["/usr/local/bin/demo-origin"]