rust-cross / rust-musl-cross

Docker images for compiling static Rust binaries using musl-cross
MIT License
625 stars 69 forks source link

add buildx compatible tags #133

Open LuckyTurtleDev opened 10 months ago

LuckyTurtleDev commented 10 months ago

This docker-images would ideal to be used in the Docker From step inside a builder, to build mutliplatform images.

FROM --platform=$BUILDPLATFORM ghcr.io/rust-cross/rust-musl-cross:aarch64-unknown-linux-musl AS builder
SHELL ["/bin/bash", "-uo", "pipefail", "-c"]

ARG version

RUN apt-get -y update && apt-get -y install protobuf-compiler musl musl-dev musl-tools
ENV PROTOC=/usr/bin/protoc
RUN echo "build version ${version}"
RUN cargo install --locked --git https://github.com/ankitects/anki.git --tag ${version} anki-sync-server
RUN ldd /usr/local/cargo/bin/anki-sync-server

FROM --platform=$BUILDPLATFORM scratch
ENV SYNC_BASE=/data
COPY --from=builder --chmod=0755 /usr/local/cargo/bin/anki-sync-server /
CMD ["./anki-sync-server"]

For this you must choose an different image tag for each platform. Docker does provide the option to use docker Args linke TARGETPLATFORM here. Which are created by buildx. So you can modifiy the From step like this:

FROM --platform=$BUILDPLATFORM ghcr.io/rust-cross/rust-musl-cross:$TARGETPLATFORM AS builder

The problem is that TARGETPLATFORM platform does not match the name of the rust toolchain. Instead it has values like linux/amd64, linux/arm64, linux/arm/v7. Sadly docker does not allow to use a function here, also variables for previous build steps can not be used, so they is currently no way to map this values to the required toolchain.

My suggestion is to add additional linux/amd64, linux/arm64, linux/arm/v7, etc tags, so TARGETPLATFORM platform can be used directly.

LuckyTurtleDev commented 8 months ago

anything new?

nbari commented 8 months ago

How are you solving this, I am trying a single Dockerfile (not very efficient, trying to find better ways) with something like:

# Build stage for x86_64
FROM messense/rust-musl-cross:x86_64-musl as builder-x86_64

RUN apt-get update && \
    apt-get install -y git libssl-dev pkg-config && \
    rm -rf /var/lib/apt/lists/*

WORKDIR /app

COPY . .

RUN cargo build --release --locked --features "openssl/vendored"

# Build stage for arm64
FROM messense/rust-musl-cross:aarch64-musl as builder-arm64

RUN apt-get update && \
    apt-get install -y git libssl-dev pkg-config && \
    rm -rf /var/lib/apt/lists/*

WORKDIR /app

COPY . .

RUN cargo build --release --locked --features "openssl/vendored"

# Runtime image
FROM alpine:latest

RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/*

# Create a non-root user
RUN adduser -D app

WORKDIR /app

# Use a variable for the binary name to handle different file extensions
ARG BINARY_NAME=s3m

# Copy the compiled binary from the appropriate builder stage
COPY --from=builder-x86_64 /app/target/x86_64-unknown-linux-musl/release/$BINARY_NAME /app/
COPY --from=builder-arm64 /app/target/aarch64-unknown-linux-musl/release/$BINARY_NAME /app/

# Set the user to the non-root user
USER app

CMD ["./s3m"]
LuckyTurtleDev commented 8 months ago

This would mean building every platform for every platform. This means you have to compile it platform-times^2 often. This sound like a bad idea.

I was able to compile without using cross see https://github.com/LuckyTurtleDev/docker-images