{"id":21823458,"url":"https://github.com/f2calv/multi-arch-container-dotnet","last_synced_at":"2026-04-01T21:15:27.601Z","repository":{"id":42530617,"uuid":"476606794","full_name":"f2calv/multi-arch-container-dotnet","owner":"f2calv","description":"Multi-architecture container build (amd64/arm64/armv7) w/.NET","archived":false,"fork":false,"pushed_at":"2026-03-21T05:31:28.000Z","size":104,"stargazers_count":13,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-21T13:02:07.944Z","etag":null,"topics":["amd64","arm64","armv7","buildx","container","docker","dotnet","multi-arch-images","multi-architecture-image"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/f2calv.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-04-01T06:51:11.000Z","updated_at":"2026-03-21T05:29:21.000Z","dependencies_parsed_at":"2024-05-03T02:35:58.157Z","dependency_job_id":"8d2eac4a-4ab7-461f-aa14-50d48c40f6a5","html_url":"https://github.com/f2calv/multi-arch-container-dotnet","commit_stats":null,"previous_names":[],"tags_count":42,"template":false,"template_full_name":null,"purl":"pkg:github/f2calv/multi-arch-container-dotnet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f2calv%2Fmulti-arch-container-dotnet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f2calv%2Fmulti-arch-container-dotnet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f2calv%2Fmulti-arch-container-dotnet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f2calv%2Fmulti-arch-container-dotnet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/f2calv","download_url":"https://codeload.github.com/f2calv/multi-arch-container-dotnet/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f2calv%2Fmulti-arch-container-dotnet/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31292099,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["amd64","arm64","armv7","buildx","container","docker","dotnet","multi-arch-images","multi-architecture-image"],"created_at":"2024-11-27T17:32:13.263Z","updated_at":"2026-04-01T21:15:27.593Z","avatar_url":"https://github.com/f2calv.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Multi-Architecture Container Image w/.NET\n\n## Introduction\n\nI'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).\n\nAs 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/).\n\nAlthough 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.\n\nThis repository provides a fully working example of building a .NET application container image that is capable of targeting multiple platform architectures - all from a single Dockerfile.\n\nIf you find this repository useful then give it a :star: ... :wink:\n\n## Goals\n\n- Construct a .NET multi-architecture container image via a single Dockerfile using the `docker buildx` command.\n- 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.\n\n  - Auto-Semantic Versioning\n  - Build App\n  - Build Container + Push To GitHub Packages\n  - Package Helm Chart + Push To GitHub Packages\n  - GitHub Release\n\n## Runtime Identifiers\n\nRID is short for [Runtime Identifier](https://docs.microsoft.com/en-us/dotnet/core/rid-catalog), these are the RID's which identify the target platforms I am interested in deploying my .NET application to;\n\n- linux-x64 (Most desktop distributions like CentOS, Debian, Fedora, Ubuntu, and derivatives)\n- linux-arm64 (Linux distributions running on 64-bit ARM like Ubuntu Server 64-bit on Raspberry Pi Model 3+)\n- linux-arm (Linux distributions running on ARM like Raspbian on Raspberry Pi Model 2+)\n  - Note: this architecture was not _plain sailing_, but I used a [great solution here](https://github.com/dotnet/dotnet-docker/issues/1537#issuecomment-755351628).\n\n## Run Pre-Built Container Image\n\n```bash\n#Run pre-built image on Docker\ndocker run --pull always --rm -it ghcr.io/f2calv/multi-arch-container-dotnet\n\n#Run pre-built image on Kubernetes (via Helm)\nhelm upgrade --install multi-arch-container-dotnet oci://ghcr.io/f2calv/charts/multi-arch-container-dotnet\n#helm uninstall multi-arch-container-dotnet\n\n#Run pre-built image on Kubernetes (via kubectl)\nkubectl run -i --tty --attach multi-arch-container-dotnet --image=ghcr.io/f2calv/multi-arch-container-dotnet --image-pull-policy='Always'\nkubectl logs -f multi-arch-container-dotnet\n#kubectl delete po multi-arch-container-dotnet\n```\n\n## Self-Build Container Image Locally\n\nThe .NET 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.\n\nFirst 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;\n\n  ```powershell\n  #demo script PowerShell version\n  ./build.ps1\n  ```\n\n  Or\n\n  ```bash\n  #demo script Shell version (also below)\n  . build.sh\n  ```\n\n### Shell Demo Script\n\n```bash\n#!/usr/bin/env bash\n\n#set variables to emulate running in the workflow/pipeline\nGIT_REPOSITORY=$(basename `git rev-parse --show-toplevel`)\nGIT_BRANCH=$(git branch --show-current)\nGIT_COMMIT=$(git rev-parse HEAD)\nGIT_TAG=\"latest-dev\"\nGITHUB_WORKFLOW=\"n/a\"\nGITHUB_RUN_ID=0\nGITHUB_RUN_NUMBER=0\nIMAGE_NAME=\"$GIT_REPOSITORY:$GIT_TAG\"\n#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.\n#$PLATFORM=\"linux/amd64,linux/arm64,linux/arm/v7\"\nPLATFORM=\"linux/amd64\"\n\n#Create a new builder instance\n#https://github.com/docker/buildx/blob/master/docs/reference/buildx_create.md\ndocker buildx create --name multiarchcontainerdotnet --use\n\n#Start a build\n#https://github.com/docker/buildx/blob/master/docs/reference/buildx_build.md\ndocker buildx build \\\n    -t $IMAGE_NAME \\\n    --label \"GITHUB_RUN_ID=$GITHUB_RUN_ID\" \\\n    --label \"IMAGE_NAME=$IMAGE_NAME\" \\\n    --build-arg GIT_REPOSITORY=$GIT_REPOSITORY \\\n    --build-arg GIT_BRANCH=$GIT_BRANCH \\\n    --build-arg GIT_COMMIT=$GIT_COMMIT \\\n    --build-arg GIT_TAG=$GIT_TAG \\\n    --build-arg GITHUB_WORKFLOW=$GITHUB_WORKFLOW \\\n    --build-arg GITHUB_RUN_ID=$GITHUB_RUN_ID \\\n    --build-arg GITHUB_RUN_NUMBER=$GITHUB_RUN_NUMBER \\\n    --platform $PLATFORM \\\n    --pull \\\n    -o type=docker \\\n    .\n\n#Preview matching images\n#https://docs.docker.com/engine/reference/commandline/images/\ndocker images $GIT_REPOSITORY\n\nread -p \"Hit ENTER to run the '$IMAGE_NAME' image...\"\n\n#Run the multi-architecture container image\n#https://docs.docker.com/engine/reference/commandline/run/\ndocker run --rm -it --name $GIT_REPOSITORY $IMAGE_NAME\n```\n\n## Docker, Container \u0026 .NET Resources\n\n- I highly recommend reading the official Docker blog posts about multi-arch images;\n\n  - https://www.docker.com/blog/multi-arch-images/\n  - https://www.docker.com/blog/multi-arch-build-and-images-the-simple-way/\n  - https://www.docker.com/blog/faster-multi-platform-builds-dockerfile-cross-compilation-guide/\n\n- Official Docker documentation about support/implementation for multi-arch images;\n\n  - https://github.com/docker/buildx\n  - https://docs.docker.com/desktop/multi-arch/\n  - https://docs.docker.com/buildx/working-with-buildx/\n  - https://docs.docker.com/engine/reference/commandline/buildx_build/\n\n- Official Microsoft documentation useful for multi-arch .NET application builds;\n\n  - https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-build\n  - https://docs.microsoft.com/en-us/dotnet/core/rid-catalog\n  - https://docs.microsoft.com/en-us/azure/container-registry/push-multi-architecture-images\n  - https://dotnet.microsoft.com/en-us/download/dotnet/10.0\n\n## Other Resources\n\n- [Click here for Rust version of this repository...](https://github.com/f2calv/multi-arch-container-rust)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ff2calv%2Fmulti-arch-container-dotnet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ff2calv%2Fmulti-arch-container-dotnet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ff2calv%2Fmulti-arch-container-dotnet/lists"}