-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(build) Setup true multiplatform dockerfile
- Loading branch information
Showing
1 changed file
with
106 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,124 @@ | ||
FROM --platform=$BUILDPLATFORM rust:1.81.0 AS chef | ||
WORKDIR /app | ||
FROM --platform=linux/amd64 lukemathwalker/cargo-chef:latest-rust-latest AS amd64-chef | ||
FROM --platform=linux/arm64 lukemathwalker/cargo-chef:latest-rust-latest AS arm64-chef | ||
|
||
# Install cargo-chef CLI | ||
RUN cargo install cargo-chef | ||
# Base image for the build stage - this is a multi-stage build that uses cross-compilation (thanks to --platform switch) | ||
FROM --platform=$BUILDPLATFORM lukemathwalker/cargo-chef:latest-rust-latest AS chef | ||
WORKDIR /app | ||
|
||
# Step 2: Prepare dependency caching | ||
# Planner stage | ||
FROM chef AS planner | ||
COPY . . | ||
# Create a recipe file for the dependencies | ||
RUN cargo chef prepare --recipe-path recipe.json | ||
|
||
# Step 3: Cache dependencies | ||
FROM chef AS cacher | ||
# Builder stage | ||
FROM chef AS builder | ||
COPY --from=planner /app/recipe.json recipe.json | ||
|
||
# Install system deps | ||
RUN apt-get update && apt-get install -y libssl-dev pkg-config | ||
ARG TARGETPLATFORM | ||
ARG TARGETARCH | ||
|
||
# Build the deps, cache the output | ||
RUN cargo chef cook --release --recipe-path recipe.json | ||
# Copy runtime dependencies for specific target platform/architecture | ||
# ARM specific folders | ||
WORKDIR /all-files/linux/arm64/lib/aarch64-linux-gnu | ||
|
||
# Step 4: Build the application | ||
FROM chef AS builder | ||
# AMD64 specific folders | ||
WORKDIR /all-files/linux/amd64/lib/x86_64-linux-gnu | ||
WORKDIR /all-files/linux/amd64/lib64 | ||
|
||
# Copy the cached dependencies | ||
COPY --from=cacher /app/target target | ||
COPY --from=cacher /usr/local/cargo /usr/local/cargo | ||
# Copy the project source code | ||
COPY . . | ||
# Common folders | ||
WORKDIR /all-files/${TARGETPLATFORM}/etc/ssl/certs | ||
WORKDIR /all-files/${TARGETPLATFORM}/app | ||
|
||
# ARM64 | ||
COPY --from=arm64-chef \ | ||
/lib/aarch64-linux-gnu/libssl.so.3 \ | ||
/lib/aarch64-linux-gnu/libcrypto.so.3 \ | ||
/lib/aarch64-linux-gnu/libgcc_s.so.1 \ | ||
/lib/aarch64-linux-gnu/libm.so.6 \ | ||
/lib/aarch64-linux-gnu/libc.so.6 \ | ||
/all-files/linux/arm64/lib/aarch64-linux-gnu/ | ||
|
||
COPY --from=arm64-chef \ | ||
/lib/ld-linux-aarch64.so.1 \ | ||
/all-files/linux/arm64/lib | ||
|
||
# AMD64 | ||
COPY --from=amd64-chef \ | ||
/lib/x86_64-linux-gnu/libssl.so.3 \ | ||
/lib/x86_64-linux-gnu/libcrypto.so.3 \ | ||
/lib/x86_64-linux-gnu/libgcc_s.so.1 \ | ||
/lib/x86_64-linux-gnu/libm.so.6 \ | ||
/lib/x86_64-linux-gnu/libc.so.6 \ | ||
/all-files/linux/amd64/lib/x86_64-linux-gnu/ | ||
|
||
COPY --from=amd64-chef \ | ||
/lib64/ld-linux-x86-64.so.2 \ | ||
/all-files/linux/amd64/lib64/ | ||
|
||
# Build the application | ||
RUN cargo build --release | ||
# Common files - certs | ||
COPY --from=amd64-chef \ | ||
/etc/ssl/certs/ca-certificates.crt \ | ||
/all-files/linux/amd64/etc/ssl/certs/ | ||
COPY --from=arm64-chef \ | ||
/etc/ssl/certs/ca-certificates.crt \ | ||
/all-files/linux/arm64/etc/ssl/certs/ | ||
|
||
# Step 5: Final arch images | ||
WORKDIR /app | ||
|
||
# Install dependencies for cross-compilation and protobuf | ||
RUN dpkg --add-architecture arm64 \ | ||
&& apt-get update \ | ||
&& apt-get install -y \ | ||
protobuf-compiler \ | ||
g++-aarch64-linux-gnu \ | ||
libc6-dev-arm64-cross \ | ||
libssl-dev:arm64 \ | ||
ca-certificates \ | ||
&& rustup target add aarch64-unknown-linux-gnu \ | ||
&& rustup toolchain install stable-aarch64-unknown-linux-gnu \ | ||
&& rm -rf /var/lib/apt/lists/* | ||
|
||
# Build dependencies - this is the caching Docker layer! | ||
RUN case ${TARGETARCH} in \ | ||
arm64) PKG_CONFIG_SYSROOT_DIR=/ CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc cargo chef cook --target=aarch64-unknown-linux-gnu --release --recipe-path recipe.json ;; \ | ||
amd64) cargo chef cook --release --recipe-path recipe.json ;; \ | ||
*) exit 1 ;; \ | ||
esac | ||
|
||
# Copy the source code | ||
COPY . /app | ||
|
||
# Build application - this is the caching Docker layer! | ||
RUN case ${TARGETARCH} in \ | ||
arm64) PKG_CONFIG_SYSROOT_DIR=/ CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc cargo build --target=aarch64-unknown-linux-gnu --release ;; \ | ||
amd64) cargo build --release ;; \ | ||
*) exit 1 ;; \ | ||
esac | ||
|
||
# Copy all the dependencies to a separate folder | ||
RUN set -ex; \ | ||
# Determine target (source folder for the binary and env files) | ||
case ${TARGETARCH} in \ | ||
arm64) target='/app/target/aarch64-unknown-linux-gnu/release';; \ | ||
amd64) target='/app/target/release';; \ | ||
*) exit 1 ;; \ | ||
esac; \ | ||
# Copy files from the target folder to app folder | ||
cp $target/unleash-edge /all-files/${TARGETPLATFORM}/app | ||
|
||
# # Create a single layer image | ||
FROM scratch AS runtime | ||
|
||
# Make build arguments available in the runtime stage | ||
ARG TARGETPLATFORM | ||
ARG TARGETARCH | ||
|
||
FROM --platform=$BUILDPLATFORM gcr.io/distroless/cc-debian12:nonroot AS final | ||
WORKDIR /app | ||
|
||
COPY --from=builder /app/target/release/unleash-edge /app/unleash-edge | ||
# Copy the binary and the environment files from the pre-runtime stage as a single layer | ||
COPY --from=builder /all-files/${TARGETPLATFORM} / | ||
|
||
# Expose the port that the application listens on. | ||
EXPOSE 3063 | ||
|
||
ENTRYPOINT ["/app/unleash-edge"] |