From e7da94889961a128999319257e1bfc9f79a66a52 Mon Sep 17 00:00:00 2001 From: dfunkt Date: Thu, 2 May 2024 22:34:52 +0300 Subject: [PATCH] Optimize Dockerfiles #2 Fetch cargo dependencies only for the build platform, cross-compiling for the rest --- docker/Dockerfile.alpine | 16 ++++++---- docker/Dockerfile.debian | 61 ++++++++++++++++++++++++-------------- docker/Dockerfile.j2 | 63 +++++++++++++++++++++++++--------------- 3 files changed, 89 insertions(+), 51 deletions(-) diff --git a/docker/Dockerfile.alpine b/docker/Dockerfile.alpine index 7f51289a93..8d727229d1 100644 --- a/docker/Dockerfile.alpine +++ b/docker/Dockerfile.alpine @@ -39,9 +39,6 @@ FROM --platform=linux/amd64 ghcr.io/blackdex/rust-musl:arm-musleabi-stable-1.77. ########################## BUILD IMAGE ########################## # hadolint ignore=DL3006 FROM --platform=linux/amd64 build_${TARGETARCH}${TARGETVARIANT} as build -ARG TARGETARCH -ARG TARGETVARIANT -ARG TARGETPLATFORM SHELL ["/bin/bash", "-o", "pipefail", "-c"] @@ -65,6 +62,16 @@ RUN mkdir -pv "${CARGO_HOME}" && \ RUN USER=root cargo new --bin /app WORKDIR /app +# Copies over *only* your manifests and build files +COPY ./Cargo.* ./rust-toolchain.toml ./build.rs ./ + +# Fetch dependencies only for the build platform, rest will be cross-compiled +RUN cargo fetch + +ARG TARGETARCH +ARG TARGETVARIANT +ARG TARGETPLATFORM + # Environment variables for Cargo on Alpine based builds RUN echo "export CARGO_TARGET=${RUST_MUSL_CROSS_TARGET}" >> /env-cargo && \ # To be able to build the armv6 image with mimalloc we need to tell the linker to also look for libatomic @@ -75,9 +82,6 @@ RUN echo "export CARGO_TARGET=${RUST_MUSL_CROSS_TARGET}" >> /env-cargo && \ RUN source /env-cargo && \ rustup target add "${CARGO_TARGET}" -# Copies over *only* your manifests and build files -COPY ./Cargo.* ./rust-toolchain.toml ./build.rs ./ - ARG CARGO_PROFILE=release # Configure the DB ARG as late as possible to not invalidate the cached layers above diff --git a/docker/Dockerfile.debian b/docker/Dockerfile.debian index b0ea02ec98..f62c83d408 100644 --- a/docker/Dockerfile.debian +++ b/docker/Dockerfile.debian @@ -37,9 +37,6 @@ FROM --platform=linux/amd64 docker.io/tonistiigi/xx@sha256:0cd3f05c72d6c9b038eb1 # hadolint ignore=DL3006 FROM --platform=$BUILDPLATFORM docker.io/library/rust:1.77.2-slim-bookworm as build COPY --from=xx / / -ARG TARGETARCH -ARG TARGETVARIANT -ARG TARGETPLATFORM SHELL ["/bin/bash", "-o", "pipefail", "-c"] @@ -63,7 +60,43 @@ RUN apt-get update && \ git \ "libc6-$(xx-info debian-arch)-cross" \ "libc6-dev-$(xx-info debian-arch)-cross" \ - "linux-libc-dev-$(xx-info debian-arch)-cross" && \ + "linux-libc-dev-$(xx-info debian-arch)-cross" + +# Create CARGO_HOME folder and don't download rust docs +RUN mkdir -pv "${CARGO_HOME}" && \ + rustup set profile minimal + +# Creates a dummy project used to grab dependencies +RUN USER=root cargo new --bin /app +WORKDIR /app + +# Copies over *only* your manifests and build files +COPY ./Cargo.* ./rust-toolchain.toml ./build.rs ./ + +# Fetch dependencies only for the build platform, rest will be cross-compiled +RUN cargo fetch + +ARG TARGETARCH +ARG TARGETVARIANT +ARG TARGETPLATFORM + +# Environment variables for Cargo on Debian based builds +ARG ARCH_OPENSSL_LIB_DIR \ + ARCH_OPENSSL_INCLUDE_DIR + +# Install clang to get `xx-cargo` working +# Install pkg-config to allow amd64 builds to find all libraries +# Install git so build.rs can determine the correct version +# Install the libc cross packages based upon the debian-arch +RUN apt-get update && \ + apt-get install -y \ + --no-install-recommends \ + clang \ + pkg-config \ + git \ + "libc6-$(xx-info debian-arch)-cross" \ + "libc6-dev-$(xx-info debian-arch)-cross" \ + "linux-libc-dev-$(xx-info debian-arch)-cross" xx-apt-get install -y \ --no-install-recommends \ gcc \ @@ -77,22 +110,9 @@ RUN apt-get update && \ apt-get download "libmariadb-dev-compat:$(xx-info debian-arch)" "libmariadb-dev:$(xx-info debian-arch)" && \ dpkg --force-all -i ./libmariadb-dev*.deb && \ # Run xx-cargo early, since it sometimes seems to break when run at a later stage - echo "export CARGO_TARGET=$(xx-cargo --print-target-triple)" >> /env-cargo - -# Create CARGO_HOME folder and don't download rust docs -RUN mkdir -pv "${CARGO_HOME}" && \ - rustup set profile minimal + echo "export CARGO_TARGET=$(xx-cargo --print-target-triple)" >> /env-cargo && \ -# Creates a dummy project used to grab dependencies -RUN USER=root cargo new --bin /app -WORKDIR /app - -# Environment variables for Cargo on Debian based builds -ARG ARCH_OPENSSL_LIB_DIR \ - ARCH_OPENSSL_INCLUDE_DIR - -RUN source /env-cargo && \ - if xx-info is-cross ; then \ +RUN if xx-info is-cross ; then \ # Some special variables if needed to override some build paths if [[ -n "${ARCH_OPENSSL_LIB_DIR}" && -n "${ARCH_OPENSSL_INCLUDE_DIR}" ]]; then \ echo "export $(echo "${CARGO_TARGET}" | tr '[:lower:]' '[:upper:]' | tr - _)_OPENSSL_LIB_DIR=${ARCH_OPENSSL_LIB_DIR}" >> /env-cargo && \ @@ -114,9 +134,6 @@ RUN source /env-cargo && \ RUN source /env-cargo && \ rustup target add "${CARGO_TARGET}" -# Copies over *only* your manifests and build files -COPY ./Cargo.* ./rust-toolchain.toml ./build.rs ./ - ARG CARGO_PROFILE=release # Configure the DB ARG as late as possible to not invalidate the cached layers above diff --git a/docker/Dockerfile.j2 b/docker/Dockerfile.j2 index 934ac35be9..ccaca45760 100644 --- a/docker/Dockerfile.j2 +++ b/docker/Dockerfile.j2 @@ -48,9 +48,6 @@ FROM --platform={{ build_stage_image[base].platform }} {{ build_stage_image[base {% if base == "debian" %} COPY --from=xx / / {% endif %} -ARG TARGETARCH -ARG TARGETVARIANT -ARG TARGETPLATFORM SHELL ["/bin/bash", "-o", "pipefail", "-c"] @@ -81,21 +78,7 @@ RUN apt-get update && \ git \ "libc6-$(xx-info debian-arch)-cross" \ "libc6-dev-$(xx-info debian-arch)-cross" \ - "linux-libc-dev-$(xx-info debian-arch)-cross" && \ - xx-apt-get install -y \ - --no-install-recommends \ - gcc \ - libmariadb3 \ - libpq-dev \ - libpq5 \ - libssl-dev \ - zlib1g-dev && \ - # Force install arch dependend mariadb dev packages - # Installing them the normal way breaks several other packages (again) - apt-get download "libmariadb-dev-compat:$(xx-info debian-arch)" "libmariadb-dev:$(xx-info debian-arch)" && \ - dpkg --force-all -i ./libmariadb-dev*.deb && \ - # Run xx-cargo early, since it sometimes seems to break when run at a later stage - echo "export CARGO_TARGET=$(xx-cargo --print-target-triple)" >> /env-cargo + "linux-libc-dev-$(xx-info debian-arch)-cross" {% endif %} # Create CARGO_HOME folder and don't download rust docs @@ -106,13 +89,50 @@ RUN mkdir -pv "${CARGO_HOME}" && \ RUN USER=root cargo new --bin /app WORKDIR /app +# Copies over *only* your manifests and build files +COPY ./Cargo.* ./rust-toolchain.toml ./build.rs ./ + +# Fetch dependencies only for the build platform, rest will be cross-compiled +RUN cargo fetch + +ARG TARGETARCH +ARG TARGETVARIANT +ARG TARGETPLATFORM + {% if base == "debian" %} # Environment variables for Cargo on Debian based builds ARG ARCH_OPENSSL_LIB_DIR \ ARCH_OPENSSL_INCLUDE_DIR -RUN source /env-cargo && \ - if xx-info is-cross ; then \ +# Install clang to get `xx-cargo` working +# Install pkg-config to allow amd64 builds to find all libraries +# Install git so build.rs can determine the correct version +# Install the libc cross packages based upon the debian-arch +RUN apt-get update && \ + apt-get install -y \ + --no-install-recommends \ + clang \ + pkg-config \ + git \ + "libc6-$(xx-info debian-arch)-cross" \ + "libc6-dev-$(xx-info debian-arch)-cross" \ + "linux-libc-dev-$(xx-info debian-arch)-cross" + xx-apt-get install -y \ + --no-install-recommends \ + gcc \ + libmariadb3 \ + libpq-dev \ + libpq5 \ + libssl-dev \ + zlib1g-dev && \ + # Force install arch dependend mariadb dev packages + # Installing them the normal way breaks several other packages (again) + apt-get download "libmariadb-dev-compat:$(xx-info debian-arch)" "libmariadb-dev:$(xx-info debian-arch)" && \ + dpkg --force-all -i ./libmariadb-dev*.deb && \ + # Run xx-cargo early, since it sometimes seems to break when run at a later stage + echo "export CARGO_TARGET=$(xx-cargo --print-target-triple)" >> /env-cargo && \ + +RUN if xx-info is-cross ; then \ # Some special variables if needed to override some build paths if [[ -n "${ARCH_OPENSSL_LIB_DIR}" && -n "${ARCH_OPENSSL_INCLUDE_DIR}" ]]; then \ echo "export $(echo "${CARGO_TARGET}" | tr '[:lower:]' '[:upper:]' | tr - _)_OPENSSL_LIB_DIR=${ARCH_OPENSSL_LIB_DIR}" >> /env-cargo && \ @@ -142,9 +162,6 @@ RUN echo "export CARGO_TARGET=${RUST_MUSL_CROSS_TARGET}" >> /env-cargo && \ RUN source /env-cargo && \ rustup target add "${CARGO_TARGET}" -# Copies over *only* your manifests and build files -COPY ./Cargo.* ./rust-toolchain.toml ./build.rs ./ - ARG CARGO_PROFILE=release {% if base == "debian" %}