# RustProxy RouterOS OCI builder - Debian Trixie Multi-arch build/push helper for RustProxy images intended for RouterOS Container. It publishes one OCI manifest for `linux/amd64` and `linux/arm64`. ## Why ARM64 builds are faster The Rust build stage is pinned to Docker BuildKit's `BUILDPLATFORM`: ```dockerfile FROM --platform=$BUILDPLATFORM rust:${RUST_VERSION}-trixie AS build ``` On an amd64 build host: - amd64 uses native `rustc` + `gcc`, - arm64 uses the same native amd64 `rustc` + `aarch64-linux-gnu-gcc`. The expensive Cargo/Rust/C compilation is therefore not executed by an ARM CPU emulator. The final Debian arm64 runtime stage can still use binfmt/QEMU briefly for `apt/dpkg` if the build host is amd64; this is normally a small part of the total build and is cacheable. ## Repository layout Copy this directory as: ```text RustProxy/ Cargo.toml Cargo.lock scripts/ routeros-oci-build/ build-routeros-oci.sh Dockerfile.routeros Dockerfile.routeros.dockerignore .env ``` Create `.env`: ```bash cp scripts/routeros-oci-build/.env.example \ scripts/routeros-oci-build/.env ``` Then edit the Zot address and credentials. ## Zot example ```env REGISTRY=zot.example.net IMAGE_NAME=network/rustproxy OCI_USERNAME=builder OCI_PASSWORD=secret BUILD_PLATFORMS=linux/amd64,linux/arm64 RUST_VERSION=1.88 DEBIAN_SUITE=trixie ``` `OCI_TOKEN` can be used instead of `OCI_PASSWORD`. Credentials are sent to `docker login` using `--password-stdin`. ## Check configuration ```bash ENV_FILE=scripts/routeros-oci-build/.env \ bash scripts/routeros-oci-build/build-routeros-oci.sh config ``` The repository root is detected using Git. If that is unavailable, the script walks upward until it finds `Cargo.toml`. ## Build and push multi-arch image ```bash ENV_FILE=scripts/routeros-oci-build/.env \ bash scripts/routeros-oci-build/build-routeros-oci.sh push ``` With RustProxy version `0.25.0` and the defaults this publishes: ```text zot.example.net/network/rustproxy:0.25.0 zot.example.net/network/rustproxy:latest zot.example.net/network/rustproxy:routeros ``` Each tag points to the same amd64 + arm64 OCI manifest. ## Local single-architecture build ```bash ENV_FILE=scripts/routeros-oci-build/.env \ bash scripts/routeros-oci-build/build-routeros-oci.sh load amd64 ``` or: ```bash ENV_FILE=scripts/routeros-oci-build/.env \ bash scripts/routeros-oci-build/build-routeros-oci.sh load arm64 ``` `load arm64` loads an ARM64 image into Docker; it does not attempt to start the container. ## Cache BuildKit cache mounts are used automatically for Cargo registry/git/target data. For short-lived CI builders, enable registry cache: ```env OCI_REGISTRY_CACHE=1 ``` It is stored in Zot as: ```text zot.example.net/network/rustproxy:buildcache ``` ## Custom/self-signed Zot CA Point `BUILDER_CONFIG` to a BuildKit configuration that trusts the registry CA, for example: ```env BUILDER_CONFIG=/etc/buildkit/buildkitd.toml ``` Docker itself must also trust the registry CA for `docker login` and manifest inspection. ## Requirements - Docker Engine - Docker Buildx - access to the Zot/OCI registry - an existing RustProxy `Cargo.lock` Do not add an ARM-native Rust builder stage. Doing that would put `rustc` and Cargo back under QEMU on an amd64 host.