diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 97183c5fc..1d5b9496c 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -12,6 +12,7 @@ concurrency: env: CARGO_TERM_COLOR: always + CARGO_NET_GIT_FETCH_WITH_CLI: "true" jobs: opa-lint: diff --git a/Dockerfile b/Dockerfile index 8dea72098..8097cb357 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,30 +13,35 @@ ARG DEBIAN_VERSION=11 ARG DEBIAN_VERSION_NAME=bullseye ARG RUSTC_VERSION=1.64.0 +ARG ZIG_VERSION=0.9.1 ARG NODEJS_VERSION=18 ARG OPA_VERSION=0.45.0 +####################################################### ## Build stage that builds the static files/frontend ## +####################################################### + FROM --platform=${BUILDPLATFORM} docker.io/library/node:${NODEJS_VERSION}-${DEBIAN_VERSION_NAME}-slim AS static-files WORKDIR /app/crates/static-files + COPY ./crates/static-files/package.json ./crates/static-files/package-lock.json /app/crates/static-files/ RUN npm ci + COPY . /app/ RUN npm run build + # Change the timestamp of built files for better caching RUN find public -type f -exec touch -t 197001010000.00 {} + +############################################## ## Build stage that builds the OPA policies ## +############################################## + FROM --platform=${BUILDPLATFORM} docker.io/library/debian:${DEBIAN_VERSION_NAME}-slim AS policy # Install make -RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache -RUN \ - --mount=type=cache,sharing=locked,target=/var/cache/apt \ - --mount=type=cache,sharing=locked,target=/var/lib/apt \ - apt update && apt install -y --no-install-recommends \ - make +RUN apt update && apt install -y --no-install-recommends make ARG BUILDOS ARG BUILDARCH @@ -52,37 +57,31 @@ RUN make -B # Change the timestamp of built files for better caching RUN touch -t 197001010000.00 {} policy.wasm +########################################################################## ## Base image with cargo-chef and the right cross-compilation toolchain ## -# cargo-chef helps with caching dependencies between builds -# The image Debian base name (bullseye) must be in sync with the runtime variant (debian11) -FROM --platform=${BUILDPLATFORM} docker.io/library/rust:${RUSTC_VERSION}-slim-${DEBIAN_VERSION_NAME} AS chef +########################################################################## -# Install x86_64 and aarch64 cross-compiling stack -RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache -RUN \ - --mount=type=cache,sharing=locked,target=/var/cache/apt \ - --mount=type=cache,sharing=locked,target=/var/lib/apt \ - apt update && apt install -y --no-install-recommends \ - g++-aarch64-linux-gnu \ - g++-x86-64-linux-gnu \ - libc6-dev-arm64-cross \ - libc6-dev-amd64-cross \ +FROM --platform=${BUILDPLATFORM} docker.io/library/rust:${RUSTC_VERSION}-slim-${DEBIAN_VERSION_NAME} AS toolchain + +ARG ZIG_VERSION +ARG RUSTC_VERSION + +# Make cargo use the git cli for fetching dependencies +ENV CARGO_NET_GIT_FETCH_WITH_CLI=true + +# Install the protobuf compiler, git, curl and xz +RUN apt update && apt install -y --no-install-recommends \ + git \ + curl \ + xz-utils \ protobuf-compiler +# Download zig compiler for cross-compilation +RUN curl -L "https://ziglang.org/download/${ZIG_VERSION}/zig-linux-$(uname -m)-${ZIG_VERSION}.tar.xz" | tar -J -x -C /usr/local && \ + ln -s "/usr/local/zig-linux-$(uname -m)-${ZIG_VERSION}/zig" /usr/local/bin/zig + WORKDIR /app -RUN \ - --mount=type=cache,sharing=private,target=/usr/local/cargo/registry \ - cargo install --locked cargo-chef - -ENV \ - CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=x86_64-linux-gnu-gcc \ - CC_x86_64_unknown_linux_gnu=x86_64-linux-gnu-gcc \ - CXX_x86_64_unknown_linux_gnu=x86_64-linux-gnu-g++ \ - CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc \ - CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc \ - CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++ - -ARG RUSTC_VERSION +RUN cargo install --locked cargo-chef cargo-zigbuild cargo-auditable # Install all cross-compilation targets RUN rustup target add --toolchain "${RUSTC_VERSION}" \ @@ -92,24 +91,28 @@ RUN rustup target add --toolchain "${RUSTC_VERSION}" \ # Helper script that transforms docker platforms to LLVM triples COPY ./misc/docker-arch-to-rust-target.sh / +##################################### ## Run the planner from cargo-chef ## -FROM --platform=${BUILDPLATFORM} chef AS planner +##################################### + +FROM --platform=${BUILDPLATFORM} toolchain AS planner COPY ./Cargo.toml ./Cargo.lock /app/ COPY ./crates /app/crates -RUN \ - --mount=type=cache,sharing=private,target=/usr/local/cargo/registry \ - cargo chef prepare --recipe-path recipe.json +RUN cargo chef prepare --recipe-path recipe.json --bin crates/cli +######################## ## Actual build stage ## -FROM --platform=${BUILDPLATFORM} chef AS builder +######################## + +FROM --platform=${BUILDPLATFORM} toolchain AS builder ARG TARGETPLATFORM # Build dependencies COPY --from=planner /app/recipe.json recipe.json -RUN \ - --mount=type=cache,sharing=private,target=/usr/local/cargo/registry \ - cargo chef cook \ +RUN cargo chef cook \ + --zigbuild \ + --bin mas-cli \ --release \ --recipe-path recipe.json \ --target $(/docker-arch-to-rust-target.sh "${TARGETPLATFORM}") \ @@ -121,9 +124,8 @@ COPY ./crates /app/crates COPY --from=static-files /app/crates/static-files/public /app/crates/static-files/public COPY --from=policy /app/crates/policy/policies/policy.wasm /app/crates/policy/policies/policy.wasm ENV SQLX_OFFLINE=true -RUN \ - --mount=type=cache,sharing=private,target=/usr/local/cargo/registry \ - cargo build \ +RUN cargo auditable zigbuild \ + --locked \ --release \ --bin mas-cli \ --target $(/docker-arch-to-rust-target.sh "${TARGETPLATFORM}") @@ -131,7 +133,9 @@ RUN \ # Move the binary to avoid having to guess its name in the next stage RUN mv target/$(/docker-arch-to-rust-target.sh "${TARGETPLATFORM}")/release/mas-cli /usr/local/bin/mas-cli +################################## ## Runtime stage, debug variant ## +################################## FROM --platform=${TARGETPLATFORM} gcr.io/distroless/cc-debian${DEBIAN_VERSION}:debug-nonroot AS debug # Inject a wasmtime config which disables cache to avoid issues running with a read-only root filesystem @@ -142,7 +146,9 @@ COPY --from=builder /usr/local/bin/mas-cli /usr/local/bin/mas-cli WORKDIR / ENTRYPOINT ["/usr/local/bin/mas-cli"] +################### ## Runtime stage ## +################### FROM --platform=${TARGETPLATFORM} gcr.io/distroless/cc-debian${DEBIAN_VERSION}:nonroot # Inject a wasmtime config which disables cache to avoid issues running with a read-only root filesystem