Skip to content

Commit

Permalink
Cross-compile for linux/arm64 and push multi-platform Docker images.
Browse files Browse the repository at this point in the history
  • Loading branch information
vitropy committed Nov 22, 2023
1 parent 5ac1fc7 commit ce33861
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 37 deletions.
40 changes: 12 additions & 28 deletions .github/workflows/container-build-and-push.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,6 @@ jobs:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_CI_TOKEN }}
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
Expand All @@ -55,35 +50,24 @@ jobs:
type=ref,event=pr
type=semver,pattern={{version}}
type=sha,format=long
- name: Build ${{ inputs.docker_build_arg_package }} container image
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Builder
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_CI_TOKEN }}
- name: Build and push ${{ inputs.docker_build_arg_package }} container image
id: docker-build
uses: docker/build-push-action@v5
with:
build-args:
platforms: linux/amd64,linux/arm64
build-args: |
PACKAGE=${{ inputs.docker_build_arg_package }}
secrets: |
credentials=${{ secrets.CI_MACHINE_USER_TOKEN }}
labels: ${{ steps.meta.outputs.labels }}
tags: ${{ steps.meta.outputs.tags }}
push: true
- name: Copy binary to local filesystem
id: copy-binary
run: |
tmpdir="$(mktemp -d)"
container_id=$(docker container run \
--rm \
--detach \
--entrypoint /bin/sleep \
$(echo "$DOCKER_METADATA_OUTPUT_TAGS" | head -n 1 | tr -d $'\n') \
99) # You're getting 99 seconds of sleeeeeeepy.
docker container cp \
${container_id}:/usr/local/bin/${{ inputs.docker_build_arg_package }} \
${tmpdir}/${{ inputs.docker_build_arg_package }}
docker container kill --signal SIGKILL "${container_id}"
echo path=${tmpdir}/${{ inputs.docker_build_arg_package }} >> $GITHUB_OUTPUT
- name: Upload ${{ inputs.docker_build_arg_package }} binary artifact
uses: actions/upload-artifact@v3
with:
name: ${{ inputs.docker_build_arg_package}}_${{ inputs.git_ref_basename }}_${{ runner.os }}_${{ runner.arch }}
path: ${{ steps.copy-binary.outputs.path }}
if-no-files-found: error
38 changes: 29 additions & 9 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ ARG UBUNTU_VERSION=20.04
# https://doc.rust-lang.org/rustc/codegen-options/index.html#strip
ARG STRIP=symbols

FROM docker.io/library/debian:${DEBIAN_CODENAME}-20230522-slim as build
FROM --platform=$BUILDPLATFORM docker.io/library/debian:${DEBIAN_CODENAME}-20230522-slim as build
ARG TARGETPLATFORM
ARG PACKAGE
ARG RUST_STABLE_VERSION
ARG UBUNTU_VERSION
Expand All @@ -23,14 +24,23 @@ RUN rm -f /etc/apt/apt.conf.d/docker-clean; \
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
export DEBIAN_FRONTEND=noninteractive \
&& dpkg --add-architecture arm64 \
&& apt-get update && apt-get install --yes --no-install-recommends \
git bash curl ca-certificates openssh-client \
pkg-config protobuf-compiler make clang \
openssl libssl-dev \
&& curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
| sh -s -- -y --no-modify-path --default-toolchain none \
&& $HOME/.cargo/bin/rustup toolchain install "${RUST_STABLE_VERSION}" --profile minimal \
openssl libssl-dev libssl-dev:arm64 \
gcc-aarch64-linux-gnu g++-aarch64-linux-gnu

# Install Rust and its componentry for the current build target.
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
| sh -s -- -y --no-modify-path --profile minimal \
--default-toolchain none \
&& $HOME/.cargo/bin/rustup default "${RUST_STABLE_VERSION}" \
&& if [ "amd64" = ${TARGETPLATFORM#"linux/"} ]; then \
export RUST_PLATFORM=x86_64; \
else \
export RUST_PLATFORM=aarch64; \
fi; $HOME/.cargo/bin/rustup toolchain install "${RUST_STABLE_VERSION}-${RUST_PLATFORM}-unknown-linux-gnu" --profile minimal \
&& $HOME/.cargo/bin/rustup component add rust-src rustfmt clippy \
&& $HOME/.cargo/bin/rustup target add wasm32-unknown-unknown

Expand Down Expand Up @@ -70,10 +80,20 @@ RUN --mount=type=ssh \
&& mkdir -p ~/.ssh \
&& echo "github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl" \
> ~/.ssh/known_hosts \
&& CARGO_NET_GIT_FETCH_WITH_CLI=true \
$HOME/.cargo/bin/cargo rustc --release -p ${PACKAGE} -- \
-C strip=${STRIP} \
&& install target/release/${PACKAGE} /usr/local/bin
&& if [ "amd64" = ${TARGETPLATFORM#"linux/"} ]; then \
export RUST_PLATFORM=x86_64; \
else \
export RUST_PLATFORM=aarch64; \
fi; $HOME/.cargo/bin/rustup target add "${RUST_PLATFORM}-unknown-linux-gnu" \
&& if [ "linux/arm64" = "${TARGETPLATFORM}" ]; then \
export PKG_CONFIG_SYSROOT_DIR="/usr/aarch64-linux-gnu"; \
export BINDGEN_EXTRA_CLANG_ARGS="-I/usr/aarch64-linux-gnu/include/"; \
fi; CARGO_NET_GIT_FETCH_WITH_CLI=true \
CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER="cc" \
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER="aarch64-linux-gnu-gcc" \
$HOME/.cargo/bin/cargo rustc --release -p "${PACKAGE}" --target "${RUST_PLATFORM}-unknown-linux-gnu" \
-- -C strip="${STRIP}" \
&& install "target/${RUST_PLATFORM}-unknown-linux-gnu/release/${PACKAGE}" /usr/local/bin

# Next stage will contain just our built binary, without dependencies.
FROM docker.io/library/ubuntu:${UBUNTU_VERSION}
Expand Down

0 comments on commit ce33861

Please sign in to comment.