From 6df68e049562224dad5280e69223626df3fbe78c Mon Sep 17 00:00:00 2001 From: Platform Engineer Date: Tue, 31 Mar 2026 20:03:29 +0300 Subject: [PATCH] harden: pin container image digest, document ARM64 QEMU trade-offs - Pin catthehacker/ubuntu:act-22.04 to digest sha256:52581951... to prevent supply-chain drift from mutable tags - Add ARM64 builds section to README documenting QEMU emulation trade-offs and when to switch to native ARM64 runners (Rust builds) - Update Notes section to reference new ARM64 docs and digest pinning Ref: CON-578 --- .gitea/workflows/build-push.yaml | 2 +- README.md | 32 +++++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/build-push.yaml b/.gitea/workflows/build-push.yaml index 625c90c..f66d89e 100644 --- a/.gitea/workflows/build-push.yaml +++ b/.gitea/workflows/build-push.yaml @@ -49,7 +49,7 @@ jobs: name: Build & Push runs-on: ${{ inputs.runner }} container: - image: catthehacker/ubuntu:act-22.04 + image: catthehacker/ubuntu:act-22.04@sha256:52581951350bf4f1137d44883626850bdfa35a8e5318b95dcb22226caece3bc9 options: --privileged outputs: image-tag: ${{ steps.tag.outputs.tag }} diff --git a/README.md b/README.md index 03118a1..2c7fb53 100644 --- a/README.md +++ b/README.md @@ -149,10 +149,40 @@ jobs: working-directory: backend # if Python code is in a subdirectory ``` +## ARM64 builds and QEMU emulation + +Our Hetzner cluster runs on ARM64 (CAX) nodes, so all Docker images target `linux/arm64` by default. Since our Gitea runners are amd64, ARM64 images are built via **QEMU user-mode emulation** through Docker Buildx. + +**Trade-offs:** + +| | QEMU emulation (default) | Native ARM64 runner | +|---|---|---| +| Setup | Zero — works on any amd64 runner | Requires provisioning a self-hosted ARM64 runner | +| Build speed | 3-10x slower for compiled languages (Rust, Go, C) | Native speed | +| Reliability | Occasional QEMU edge cases with complex syscalls | No emulation issues | +| Best for | Node/Python/lightweight builds | Rust services, heavy native compilation | + +**For Rust services** (e.g. wectrl-telemetry): QEMU emulation of ARM64 Rust compilation is significantly slower. When build times exceed ~10 minutes, switch to a native ARM64 runner: + +```yaml +jobs: + build: + uses: wectrl-net/ci-templates/.gitea/workflows/build-push.yaml@main + with: + image-name: git.wectrl.net/wectrl-net/wectrl-telemetry + runner: self-hosted-arm64 # bypass QEMU, use native ARM64 runner + secrets: + REGISTRY_USER: ${{ secrets.REGISTRY_USER }} + REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }} +``` + +The `runner` input on `build-push.yaml` defaults to `ubuntu-latest` (amd64 + QEMU). Set it to your ARM64 runner label when needed. + ## Notes - All workflows trigger on both `main` and `dev` branches (per CON-569 branching strategy) - Build & deploy only runs on push to `main` (production deploy) - Dev/staging deploys can be added by extending `deploy-k8s.yaml` with a branch condition -- The runner is ARM64 (`linux/arm64`) matching the Hetzner CAX cluster nodes +- The default platform is ARM64 (`linux/arm64`) matching the Hetzner CAX cluster nodes — see [ARM64 builds](#arm64-builds-and-qemu-emulation) above - Semantic versioning tags (`v1.2.3`) are supported by `build-push.yaml` via the metadata action +- Container images used by CI (e.g. `catthehacker/ubuntu`) are pinned by digest to prevent supply-chain drift