Speed up ARM production release builds - #480
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR reworks the production Docker release pipeline to significantly reduce ARM build times by switching ARM64 builds to a native ARM runner and cross-compiling ARMv7 on amd64 (leaving QEMU primarily for target runtime-layer assembly), while also improving layer/cache reuse and reducing Docker build context size.
Changes:
- Updates the Docker publish workflow to use a platform→runner matrix (native ARM64 runner) and per-platform BuildKit registry caches.
- Adjusts the Dockerfile to support ARMv7 cross-compilation via Debian armhf multiarch packages + an ARMv7 CMake toolchain, and disables production test builds.
- Adds
.dockerignoreand documents the updated release build approach.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
scripts/build.sh |
Adds optional CMAKE_TOOLCHAIN_FILE forwarding into the CMake configure step. |
docs/RELEASE_PROCESS.md |
Documents native ARM64 runner usage, ARMv7 cross-compilation, and per-platform cache behavior. |
Dockerfile |
Implements cross-build logic for ARMv7, uses $BUILDPLATFORM for the builder stage, and adjusts build steps/env for multiarch. |
cmake/toolchains/armv7-linux-gnueabihf.cmake |
Introduces an ARMv7 hard-float/NEON toolchain file for cross-compiling via Debian multiarch. |
.gitignore |
Ensures the new toolchain .cmake files under cmake/toolchains/ aren’t ignored. |
.github/workflows/docker-publish.yml |
Moves to a matrix with platform-specific runners/QEMU and adds per-platform registry cache import/export. |
.dockerignore |
Shrinks Docker build context by excluding VCS/CI/dev artifacts and other large directories. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 12 changed files in this pull request and generated 2 comments.
Suppressed comments (2)
Dockerfile:216
- This
case "$TARGETARCH/$TARGETVARIANT"only matches whenTARGETVARIANTis empty. If the builder provides a variant likearm64/v8, this will incorrectly fail withUnsupported target architecturewhile building go2rtc.
amd64/) GOARCH=amd64; GOARM= ;; \
arm64/) GOARCH=arm64; GOARM= ;; \
arm/v7) GOARCH=arm; GOARM=7 ;; \
*) echo "Unsupported target architecture: $TARGETARCH/$TARGETVARIANT"; exit 1 ;; \
Dockerfile:268
- These patterns assume
TARGETVARIANTis empty for amd64/arm64 (matchingamd64/andarm64/). If a non-empty variant is provided (e.g.arm64/v8), the build will fail as an unsupported architecture when selecting pkg-config paths.
amd64/) PKG_CONFIG_ARCH_PATH="/usr/lib/x86_64-linux-gnu/pkgconfig"; TOOLCHAIN_FILE="" ;; \
arm64/) PKG_CONFIG_ARCH_PATH="/usr/lib/aarch64-linux-gnu/pkgconfig"; TOOLCHAIN_FILE="" ;; \
Comment on lines
+182
to
+184
| cmake --build /tmp/flatc-build -j"$(nproc)" && \ | ||
| test -x /opt/host-tools/bin/flatc && \ | ||
| /opt/host-tools/bin/flatc --version; \ |
Comment on lines
+195
to
+198
| amd64/) LIB_DIR="/usr/lib/x86_64-linux-gnu"; MBEDTLS_PACKAGE=libmbedtls-dev ;; \ | ||
| arm64/) LIB_DIR="/usr/lib/aarch64-linux-gnu"; MBEDTLS_PACKAGE=libmbedtls-dev ;; \ | ||
| arm/v7) LIB_DIR="/usr/lib/arm-linux-gnueabihf"; MBEDTLS_PACKAGE=libmbedtls-dev:armhf ;; \ | ||
| *) echo "Unsupported target architecture: $TARGETARCH/$TARGETVARIANT"; exit 1 ;; \ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
linux/arm64build on GitHub's nativeubuntu-24.04-armrunnerlinux/arm/v7on x86_64 with Debian armhf multiarch packages and a native LiteRTflatchost tool.dockerignore, omit recommended build-only packages, and skip compiling the unused test target in production imagesWhy
In release run 30839856661, the jobs took:
linux/amd64: 15m44slinux/arm/v7: 3h42m48slinux/arm64: 4h58m47sThe ARM jobs were compiling the complete LiteRT/XNNPACK dependency tree under QEMU. In the ARMv7 log, the final LightNVR build layer alone took about 2h55m. Docker documents compilation as a case where QEMU can be much slower than native execution and recommends native nodes or cross-compilation.
The existing Debian release matrix already demonstrates the native ARM64 runner path: its ARM64 jobs finish in roughly 10–13 minutes, while emulated ARMv7 jobs take about two hours.
Validation
docker buildx build --platform linux/arm/v7 --target builder --output type=cacheonly ./bin/lightnvrand/bin/go2rtcare 32-bit ARM EABI5 binariesdocker buildx build --platform linux/amd64 --output type=cacheonly .docker buildx build --checkfor amd64, arm64, and arm/v7actionlint .github/workflows/docker-publish.ymlbash -n scripts/build.sh, andgit diff --checkThe first release still has to populate the new registry caches, but ARMv7 compilation no longer runs under emulation. Subsequent releases can also reuse unchanged dependency layers.