Skip to content

Commit bf0d100

Browse files
Merge pull request #190 from code-inflation/feature/faster-docker-arm-builds
feat: Implement cross-compilation and Docker layer caching for ARM bu…
2 parents b749478 + 08b26ee commit bf0d100

File tree

3 files changed

+157
-12
lines changed

3 files changed

+157
-12
lines changed

.github/workflows/CI.yml

Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,82 @@ jobs:
3636
- uses: actions/checkout@v4
3737
- name: Set up Docker Buildx
3838
uses: docker/setup-buildx-action@v3
39-
- name: Build and push Docker image
39+
- name: Set up Docker Buildx cache
40+
uses: actions/cache@v3
41+
with:
42+
path: /tmp/.buildx-cache
43+
key: ${{ runner.os }}-buildx-${{ github.sha }}
44+
restore-keys: |
45+
${{ runner.os }}-buildx-
46+
- name: Build Docker image for amd64
47+
uses: docker/build-push-action@v5
48+
with:
49+
platforms: linux/amd64
50+
push: false
51+
tags: |
52+
cybuerg/cfspeedtest:${{ github.sha }}-amd64
53+
cache-from: type=local,src=/tmp/.buildx-cache
54+
cache-to: type=local,dest=/tmp/.buildx-cache-amd64,mode=max
55+
outputs: type=docker,dest=/tmp/docker-image-amd64.tar
56+
57+
- name: Build Docker image for arm64
4058
uses: docker/build-push-action@v5
4159
with:
42-
platforms: linux/amd64,linux/arm64
60+
platforms: linux/arm64
4361
push: false
4462
tags: |
45-
cybuerg/cfspeedtest:${{ github.sha }}
63+
cybuerg/cfspeedtest:${{ github.sha }}-arm64
64+
cache-from: type=local,src=/tmp/.buildx-cache
65+
cache-to: type=local,dest=/tmp/.buildx-cache-arm64,mode=max
66+
outputs: type=docker,dest=/tmp/docker-image-arm64.tar
67+
- name: Merge and move cache
68+
run: |
69+
mkdir -p /tmp/.buildx-cache-new
70+
cp -r /tmp/.buildx-cache-amd64/* /tmp/.buildx-cache-new/ || true
71+
cp -r /tmp/.buildx-cache-arm64/* /tmp/.buildx-cache-new/ || true
72+
rm -rf /tmp/.buildx-cache
73+
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
74+
- name: Upload Docker images as artifacts
75+
uses: actions/upload-artifact@v4
76+
with:
77+
name: docker-images
78+
path: |
79+
/tmp/docker-image-amd64.tar
80+
/tmp/docker-image-arm64.tar
81+
retention-days: 1
82+
83+
verify-docker-image:
84+
needs: docker-build
85+
runs-on: ubuntu-latest
86+
strategy:
87+
matrix:
88+
platform: [linux/amd64, linux/arm64]
89+
steps:
90+
- name: Download Docker images
91+
uses: actions/download-artifact@v4
92+
with:
93+
name: docker-images
94+
path: /tmp
95+
- name: Load Docker image
96+
run: |
97+
if [ "${{ matrix.platform }}" = "linux/amd64" ]; then
98+
docker load < /tmp/docker-image-amd64.tar
99+
else
100+
docker load < /tmp/docker-image-arm64.tar
101+
fi
102+
- name: Verify amd64 image
103+
if: matrix.platform == 'linux/amd64'
104+
run: |
105+
docker run cybuerg/cfspeedtest:${{ github.sha }}-amd64 --help
106+
docker run --entrypoint /bin/sh cybuerg/cfspeedtest:${{ github.sha }}-amd64 -c "file /usr/local/bin/cfspeedtest" | grep "x86-64"
107+
- name: Set up QEMU
108+
if: matrix.platform == 'linux/arm64'
109+
uses: docker/setup-qemu-action@v3
110+
with:
111+
platforms: arm64
112+
113+
- name: Verify arm64 image
114+
if: matrix.platform == 'linux/arm64'
115+
run: |
116+
docker run --platform linux/arm64 cybuerg/cfspeedtest:${{ github.sha }}-arm64 --help
117+
docker run --platform linux/arm64 --entrypoint /bin/sh cybuerg/cfspeedtest:${{ github.sha }}-arm64 -c "file /usr/local/bin/cfspeedtest" | grep "aarch64"

.github/workflows/release.yaml

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,55 @@ jobs:
5252
- uses: actions/checkout@v4
5353
- name: Set up Docker Buildx
5454
uses: docker/setup-buildx-action@v3
55+
- name: Set up Docker Buildx cache
56+
uses: actions/cache@v3
57+
with:
58+
path: /tmp/.buildx-cache
59+
key: ${{ runner.os }}-buildx-${{ github.sha }}
60+
restore-keys: |
61+
${{ runner.os }}-buildx-
5562
- name: Log in to DockerHub
5663
uses: docker/login-action@v3
5764
with:
5865
username: ${{ secrets.DOCKERHUB_USERNAME }}
5966
password: ${{ secrets.DOCKERHUB_TOKEN }}
60-
- name: Build and push Docker image
67+
- name: Build and push Docker image for amd64
68+
uses: docker/build-push-action@v5
69+
with:
70+
platforms: linux/amd64
71+
push: true
72+
tags: |
73+
cybuerg/cfspeedtest:${{ github.ref_name }}-amd64
74+
cybuerg/cfspeedtest:latest-amd64
75+
cache-from: type=local,src=/tmp/.buildx-cache
76+
cache-to: type=local,dest=/tmp/.buildx-cache-amd64,mode=max
77+
78+
- name: Build and push Docker image for arm64
6179
uses: docker/build-push-action@v5
6280
with:
63-
platforms: linux/amd64,linux/arm64
81+
platforms: linux/arm64
6482
push: true
6583
tags: |
66-
cybuerg/cfspeedtest:${{ github.ref_name }}
67-
cybuerg/cfspeedtest:latest
84+
cybuerg/cfspeedtest:${{ github.ref_name }}-arm64
85+
cybuerg/cfspeedtest:latest-arm64
86+
cache-from: type=local,src=/tmp/.buildx-cache
87+
cache-to: type=local,dest=/tmp/.buildx-cache-arm64,mode=max
88+
89+
- name: Create and push multi-platform manifest
90+
run: |
91+
docker manifest create cybuerg/cfspeedtest:${{ github.ref_name }} \
92+
cybuerg/cfspeedtest:${{ github.ref_name }}-amd64 \
93+
cybuerg/cfspeedtest:${{ github.ref_name }}-arm64
94+
docker manifest create cybuerg/cfspeedtest:latest \
95+
cybuerg/cfspeedtest:latest-amd64 \
96+
cybuerg/cfspeedtest:latest-arm64
97+
docker manifest push cybuerg/cfspeedtest:${{ github.ref_name }}
98+
docker manifest push cybuerg/cfspeedtest:latest
99+
100+
- name: Merge and move cache
101+
run: |
102+
mkdir -p /tmp/.buildx-cache-new
103+
cp -r /tmp/.buildx-cache-amd64/* /tmp/.buildx-cache-new/ || true
104+
cp -r /tmp/.buildx-cache-arm64/* /tmp/.buildx-cache-new/ || true
105+
rm -rf /tmp/.buildx-cache
106+
mv /tmp/.buildx-cache-new /tmp/.buildx-cache

Dockerfile

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,46 @@
1-
FROM rust:slim-bullseye as builder
1+
FROM --platform=$BUILDPLATFORM rust:slim-bullseye as builder
2+
3+
# Install cross-compilation tools if needed
4+
ARG BUILDPLATFORM
5+
ARG TARGETPLATFORM
6+
RUN if [ "$TARGETPLATFORM" = "linux/arm64" ] && [ "$BUILDPLATFORM" = "linux/amd64" ]; then \
7+
dpkg --add-architecture arm64 && \
8+
apt-get update && \
9+
apt-get install -y --no-install-recommends \
10+
gcc-aarch64-linux-gnu libc6-dev-arm64-cross && \
11+
rustup target add aarch64-unknown-linux-gnu && \
12+
rm -rf /var/lib/apt/lists/*; \
13+
fi
14+
15+
# Set the correct target
16+
ARG RUST_TARGET="x86_64-unknown-linux-gnu"
17+
RUN if [ "$TARGETPLATFORM" = "linux/arm64" ]; then \
18+
echo "RUST_TARGET=aarch64-unknown-linux-gnu"; \
19+
export RUST_TARGET="aarch64-unknown-linux-gnu"; \
20+
fi
21+
22+
# Create a new empty project for caching dependencies
223
WORKDIR /usr/src/cfspeedtest
324
COPY Cargo.toml Cargo.lock ./
25+
RUN mkdir -p src && \
26+
echo "fn main() {}" > src/main.rs && \
27+
echo "pub fn dummy() {}" > src/lib.rs && \
28+
cargo fetch
29+
30+
# Build the actual application
431
COPY src ./src
5-
RUN cargo install --path .
32+
RUN if [ "$TARGETPLATFORM" = "linux/arm64" ]; then \
33+
RUSTFLAGS="-C linker=aarch64-linux-gnu-gcc" \
34+
cargo build --release --target aarch64-unknown-linux-gnu && \
35+
cp target/aarch64-unknown-linux-gnu/release/cfspeedtest /usr/local/bin/; \
36+
else \
37+
cargo build --release && \
38+
cp target/release/cfspeedtest /usr/local/bin/; \
39+
fi
640

7-
FROM debian:bullseye-slim
8-
RUN apt-get update && apt-get install -y --no-install-recommends tini && rm -rf /var/lib/apt/lists/*
9-
COPY --from=builder /usr/local/cargo/bin/cfspeedtest /usr/local/bin/cfspeedtest
41+
FROM --platform=$TARGETPLATFORM debian:bullseye-slim
42+
RUN apt-get update && apt-get install -y --no-install-recommends tini file && rm -rf /var/lib/apt/lists/*
43+
COPY --from=builder /usr/local/bin/cfspeedtest /usr/local/bin/cfspeedtest
1044

1145
# tini will be PID 1 and handle signal forwarding and process reaping
1246
ENTRYPOINT ["/usr/bin/tini", "--", "cfspeedtest"]

0 commit comments

Comments
 (0)