diff --git a/.github/workflows/test_relay.yml b/.github/workflows/test_relay.yml index 8cd1507..111ae3a 100644 --- a/.github/workflows/test_relay.yml +++ b/.github/workflows/test_relay.yml @@ -31,9 +31,14 @@ jobs: with: context: . file: relay/Dockerfile + build-args: | + ARCH=x86_64-unknown-linux-musl + target: builder outputs: type=docker,dest=/tmp/app-image.tar + tags: tacoq-relay:latest + cache-from: type=gha cache-to: type=gha,mode=max diff --git a/relay/Dockerfile b/relay/Dockerfile index 936fc40..318e1f5 100644 --- a/relay/Dockerfile +++ b/relay/Dockerfile @@ -1,9 +1,34 @@ -# Base image for chef -FROM rust:1.82.0 AS chef +# Base image for chef --------------------------------------------------------- + +FROM rust:1.86.0 AS chef + +# ============================================================================= +# Architecture-specific build: +# - aarch64-unknown-linux-musl +# - x86_64-unknown-linux-musl +# ============================================================================= + +# Verify ARCH is set to a valid architecture +ARG ARCH +RUN if [ "$ARCH" != "aarch64-unknown-linux-musl" ] && [ "$ARCH" != "x86_64-unknown-linux-musl" ]; then \ + echo "Error: ARCH must be either 'aarch64-unknown-linux-musl' or 'x86_64-unknown-linux-musl', but was instead '$ARCH'" && \ + exit 1; \ + fi + +# Check if building on compatible architecture +RUN host_arch=$(uname -m); \ + if [ "$ARCH" = "aarch64-unknown-linux-musl" ] && [ "$host_arch" != "aarch64" ]; then \ + echo "Error: Cannot build aarch64 target on $host_arch architecture" && exit 1; \ + elif [ "$ARCH" = "x86_64-unknown-linux-musl" ] && [ "$host_arch" != "x86_64" ]; then \ + echo "Error: Cannot build x86_64 target on $host_arch architecture" && exit 1; \ + fi + +# Install cargo-chef for caching compilation WORKDIR /server RUN cargo install cargo-chef -# Planner stage +# Planner stage --------------------------------------------------------------- + FROM chef AS planner WORKDIR /app @@ -11,38 +36,51 @@ WORKDIR /app COPY . . # Create recipe -RUN cargo chef prepare --recipe-path recipe.json +RUN cargo chef prepare --recipe-path recipe-${ARCH}.json -# Builder stage +# Builder stage ---------------------------------------------------------------- FROM chef AS builder WORKDIR /app -# Install curl for health checks -RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/* +# Install: +# - curl for health checks +# - musl-tools and musl-dev for building a static binary +RUN apt-get update && \ + apt-get install -y \ + curl \ + musl-tools \ + musl-dev && \ + rm -rf /var/lib/apt/lists/* -# First get the recipe -COPY --from=planner /app/recipe.json recipe.json +# Add the statically linked Rust target for the target architecture +RUN rustup target add ${ARCH} + +# Get the Chef Recipe to build the dependencies +COPY --from=planner /app/recipe-${ARCH}.json recipe-${ARCH}.json # Cook dependencies -RUN cargo chef cook --release --recipe-path recipe.json +RUN cargo chef cook --release --recipe-path recipe-${ARCH}.json --target ${ARCH} -# Copy the whole workspace structure COPY . . -# Build the specific service +# Build the service WITHOUT a Postgres connection ENV SQLX_OFFLINE=true -RUN cargo build --release --bin relay +RUN cargo build --release --bin relay --target ${ARCH} + +# Strip the binary to reduce size +RUN strip target/${ARCH}/release/relay -# Strip the binary -RUN strip target/release/relay +# Release stage ---------------------------------------------------------------- -# Final stage -FROM gcr.io/distroless/cc-debian12:nonroot AS release +FROM scratch AS release +ARG ARCH WORKDIR /app # Copy the binary from the correct location -COPY --from=builder /app/target/release/relay . +COPY --from=builder /app/target/${ARCH}/release/relay . +# Expose Axum port EXPOSE 3000 +# Run the binary CMD ["./relay"]