https://github.com/f2calv/multi-arch-container-rust
Multi-architecture container build (amd64/arm64/armv7) w/Rust
https://github.com/f2calv/multi-arch-container-rust
amd64 arm64 armv7 buildx container docker multi-arch-images multi-architecture-image rust rustlang
Last synced: 6 months ago
JSON representation
Multi-architecture container build (amd64/arm64/armv7) w/Rust
- Host: GitHub
- URL: https://github.com/f2calv/multi-arch-container-rust
- Owner: f2calv
- License: mit
- Created: 2022-12-02T05:58:06.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-08-12T08:17:21.000Z (11 months ago)
- Last Synced: 2024-11-27T17:37:59.461Z (8 months ago)
- Topics: amd64, arm64, armv7, buildx, container, docker, multi-arch-images, multi-architecture-image, rust, rustlang
- Language: Dockerfile
- Homepage:
- Size: 120 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Multi-Architecture Container Image w/Rust
## Introduction
I've been developing a service orientated smart home system which consists of a number of containerised workloads running on an edge Kubernetes cluster (via [Microk8s](https://github.com/canonical/microk8s)), the "cluster" itself is a sole Raspberry Pi 4b (ARMv8).
As well as running multiple workloads on the Pi 4b I also run workloads on another Raspberry Pi 2b (ARMv7) which is much older (but very power efficient). And finally I also need to run general tests of the workloads on my local Windows development machine prior to deployment to my "Production cluster", and at a later date I may even want to run these workloads on [Azure Kubernetes Service](https://azure.microsoft.com/en-us/products/kubernetes-service/).
Although I could achieve my goal of deploying the same application to multiple architectures using separate Dockerfiles (i.e. Dockerfile.amd64, Dockerfile.arm64, etc...) in my view that is messy and makes the CI/CD more complex. I think the single Dockerfile is the elegant approach keeping all build instructions in one place.
This repository provides a fully working example of building a Rust application container image that is capable of targeting multiple platform architectures - all from a single Dockerfile.
If you find this repository useful then give it a :star: ... :wink:
## Goals
- Construct a Rust multi-architecture container image via a single Dockerfile using the `docker buildx` command.
- Create a single GitHub Actions workflow [ci.yml](.github/workflows/ci.yml) to handle all tasks and host the reuseable workflows in an external [gha-workflows](https://github.com/f2calv/gha-workflows) repository.- Auto-Semantic Versioning
- Build App
- Build Container + Push To GitHub Packages
- Package Helm Chart + Push To GitHub Packages
- GitHub Release## Run Pre-Built Container Image
```bash
#Run pre-built image on Docker
docker run --pull always --rm -it ghcr.io/f2calv/multi-arch-container-rust#Run pre-built image on Kubernetes (via Helm)
helm upgrade --install multi-arch-container-rust oci://ghcr.io/f2calv/charts/multi-arch-container-rust
#helm uninstall multi-arch-container-rust#Run pre-built image on Kubernetes (via kubectl)
kubectl run -i --tty --attach multi-arch-container-rust --image=ghcr.io/f2calv/multi-arch-container-rust --image-pull-policy='Always'
kubectl logs -f multi-arch-container-rust
#kubectl delete po multi-arch-container-rust
```## Self-Build Container Image Locally
The Rust workload is an ultra simple worker process (i.e. a console application) which loops outputting a number of environment variables passed in during the CI process and then baked into the container image.
First clone the repository (ideally by opening it as [vscode devcontainer](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)) and then via a terminal window from the root of the repository execute;
```powershell
#demo script PowerShell version
./build.ps1
```
Or
```bash
#demo script Shell version (also below)
. build.sh
```### Shell Demo Script
```bash
#!/bin/sh#set variables to emulate running in the workflow/pipeline
GIT_REPOSITORY=$(basename `git rev-parse --show-toplevel`)
GIT_BRANCH=$(git branch --show-current)
GIT_COMMIT=$(git rev-parse HEAD)
GIT_TAG="latest-dev"
GITHUB_WORKFLOW="n/a"
GITHUB_RUN_ID=0
GITHUB_RUN_NUMBER=0
IMAGE_NAME="$GIT_REPOSITORY:$GIT_TAG"
#Note: you cannot export a buildx container image into a local docker instance with multiple architecture manifests so for local testing you have to select just a single architecture.
#$PLATFORM="linux/amd64,linux/arm64,linux/arm/v7"
PLATFORM="linux/amd64"#Create a new builder instance
#https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md
docker buildx create --name multiarchcontainerrust --use#Start a build
#https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md
docker buildx build \
-t $IMAGE_NAME \
--label "GITHUB_RUN_ID=$GITHUB_RUN_ID" \
--label "IMAGE_NAME=$IMAGE_NAME" \
--build-arg GIT_REPOSITORY=$GIT_REPOSITORY \
--build-arg GIT_BRANCH=$GIT_BRANCH \
--build-arg GIT_COMMIT=$GIT_COMMIT \
--build-arg GIT_TAG=$GIT_TAG \
--build-arg GITHUB_WORKFLOW=$GITHUB_WORKFLOW \
--build-arg GITHUB_RUN_ID=$GITHUB_RUN_ID \
--build-arg GITHUB_RUN_NUMBER=$GITHUB_RUN_NUMBER \
--platform $PLATFORM \
--pull \
-o type=docker \
.#Preview matching images
#https://docs.docker.com/engine/reference/commandline/images/
docker images $GIT_REPOSITORYread -p "Hit ENTER to run the '$IMAGE_NAME' image..."
#Run the multi-architecture container image
#https://docs.docker.com/engine/reference/commandline/run/
docker run --rm -it --name $GIT_REPOSITORY $IMAGE_NAME#userprofile=$(wslpath "$(wslvar USERPROFILE)")
#export KUBECONFIG=$userprofile/.kube/config
#kubectl run -i --tty --attach multi-arch-container-rust --image=gcr.io/f2calv/multi-arch-container-rust --image-pull-policy='Always'
```## Docker, Container & Rust Resources
- I highly recommend reading the official Docker blog posts about multi-arch images;
- https://www.docker.com/blog/multi-arch-images/
- https://www.docker.com/blog/multi-arch-build-and-images-the-simple-way/
- https://www.docker.com/blog/faster-multi-platform-builds-dockerfile-cross-compilation-guide/
- https://www.docker.com/blog/cross-compiling-rust-code-for-multiple-architectures/- Official Docker documentation about support/implementation for multi-arch images;
- https://github.com/docker/buildx
- https://docs.docker.com/desktop/multi-arch/
- https://docs.docker.com/buildx/working-with-buildx/
- https://docs.docker.com/engine/reference/commandline/buildx_build/- Official Rust documentation useful for multi-arch builds;
- https://rust-lang.github.io/rustup/cross-compilation.html
- https://doc.rust-lang.org/nightly/rustc/platform-support.html## Other Resources
- [Click here for .NET version of this repository...](https://github.com/f2calv/multi-arch-container-dotnet)