From 2b1d77927958884d39f8245519d77467f973f4f2 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Tue, 13 Jan 2026 14:07:21 -0600 Subject: [PATCH] Add multi-architecture build support (amd64, arm64) --- .gitlab-ci.yml | 54 +++++++++++++++----------------------------------- Dockerfile | 22 +++++++++++++++++--- 2 files changed, 35 insertions(+), 41 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4ae7ecc..1e56458 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -55,7 +55,7 @@ build:test: - main - tags -# Build and push for main branch +# Build and push for main branch (multi-architecture) build:main: stage: build image: docker:24-dind @@ -63,14 +63,17 @@ build:main: - docker:24-dind before_script: - docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_TOKEN + # Enable buildx for multi-arch + - docker buildx create --use --name multiarch-builder + - docker buildx inspect --bootstrap script: - | - docker build \ + docker buildx build \ + --platform linux/amd64,linux/arm64 \ --tag $REGISTRY/$IMAGE_NAME:latest \ --tag $REGISTRY/$IMAGE_NAME:main-$CI_COMMIT_SHORT_SHA \ + --push \ . - - docker push $REGISTRY/$IMAGE_NAME:latest - - docker push $REGISTRY/$IMAGE_NAME:main-$CI_COMMIT_SHORT_SHA - echo "IMAGE_TAG=latest" >> build.env artifacts: reports: @@ -78,42 +81,10 @@ build:main: only: - main -# Release build for tags (versioned releases) -release: +# Release build for tags (multi-architecture) +release:multiarch: stage: release image: docker:24-dind - services: - - docker:24-dind - before_script: - - docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_TOKEN - script: - - | - # Extract version from tag (assumes tags like v0.1.0) - VERSION=${CI_COMMIT_TAG#v} - - docker build \ - --tag $REGISTRY/$IMAGE_NAME:$VERSION \ - --tag $REGISTRY/$IMAGE_NAME:$CI_COMMIT_TAG \ - --tag $REGISTRY/$IMAGE_NAME:latest \ - . - - docker push $REGISTRY/$IMAGE_NAME:$VERSION - docker push $REGISTRY/$IMAGE_NAME:$CI_COMMIT_TAG - docker push $REGISTRY/$IMAGE_NAME:latest - - echo "Released version: $VERSION" - echo "IMAGE_TAG=$VERSION" >> release.env - artifacts: - reports: - dotenv: release.env - only: - - tags - except: - - branches - -build:multiarch: - stage: build - image: docker:24-dind services: - docker:24-dind before_script: @@ -128,8 +99,15 @@ build:multiarch: docker buildx build \ --platform linux/amd64,linux/arm64 \ --tag $REGISTRY/$IMAGE_NAME:$VERSION \ + --tag $REGISTRY/$IMAGE_NAME:$CI_COMMIT_TAG \ --tag $REGISTRY/$IMAGE_NAME:latest \ --push \ . + + echo "Released version: $VERSION" + echo "IMAGE_TAG=$VERSION" >> release.env + artifacts: + reports: + dotenv: release.env only: - tags diff --git a/Dockerfile b/Dockerfile index df02c71..dd8cd4f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,23 @@ # Build stage FROM rust:1.83-alpine AS builder +# Build arguments provided by Docker buildx +ARG TARGETPLATFORM + WORKDIR /app # Install build dependencies RUN apk add --no-cache musl-dev protobuf-dev +# Determine Rust target based on platform and add it +RUN case "$TARGETPLATFORM" in \ + "linux/amd64") RUST_TARGET="x86_64-unknown-linux-musl" ;; \ + "linux/arm64") RUST_TARGET="aarch64-unknown-linux-musl" ;; \ + *) echo "Unsupported platform: $TARGETPLATFORM" && exit 1 ;; \ + esac && \ + echo "$RUST_TARGET" > /tmp/rust-target && \ + rustup target add "$RUST_TARGET" + # Copy manifests and build files COPY Cargo.toml Cargo.lock build.rs ./ COPY proto ./proto @@ -14,7 +26,8 @@ COPY proto ./proto RUN mkdir src && echo "fn main() {}" > src/main.rs # Build dependencies (cached layer) -RUN cargo build --release --target x86_64-unknown-linux-musl +RUN RUST_TARGET=$(cat /tmp/rust-target) && \ + cargo build --release --target "$RUST_TARGET" # Remove dummy src RUN rm -rf src @@ -23,7 +36,10 @@ RUN rm -rf src COPY src ./src # Build the actual application -RUN touch src/main.rs && cargo build --release --target x86_64-unknown-linux-musl +RUN RUST_TARGET=$(cat /tmp/rust-target) && \ + touch src/main.rs && \ + cargo build --release --target "$RUST_TARGET" && \ + cp "target/$RUST_TARGET/release/towerops-agent" /tmp/towerops-agent # Runtime stage FROM alpine:3.19 @@ -35,7 +51,7 @@ RUN apk add --no-cache ca-certificates RUN mkdir -p /data # Copy binary from builder -COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/towerops-agent /usr/local/bin/ +COPY --from=builder /tmp/towerops-agent /usr/local/bin/towerops-agent # Volume for database VOLUME ["/data"]