{"id":13597547,"url":"https://github.com/ckulka/docker-multi-arch-example","last_synced_at":"2025-04-10T01:30:55.764Z","repository":{"id":97334017,"uuid":"135938196","full_name":"ckulka/docker-multi-arch-example","owner":"ckulka","description":"TL;DR reference for building multi-arch Docker images on Docker Hub","archived":false,"fork":false,"pushed_at":"2023-05-01T20:19:33.000Z","size":60,"stargazers_count":70,"open_issues_count":2,"forks_count":16,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-06T21:44:29.655Z","etag":null,"topics":["arm","docker"],"latest_commit_sha":null,"homepage":"","language":"Dockerfile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ckulka.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2018-06-03T20:29:14.000Z","updated_at":"2024-04-30T20:15:32.000Z","dependencies_parsed_at":"2024-11-06T21:46:19.430Z","dependency_job_id":null,"html_url":"https://github.com/ckulka/docker-multi-arch-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ckulka%2Fdocker-multi-arch-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ckulka%2Fdocker-multi-arch-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ckulka%2Fdocker-multi-arch-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ckulka%2Fdocker-multi-arch-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ckulka","download_url":"https://codeload.github.com/ckulka/docker-multi-arch-example/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248140251,"owners_count":21054268,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["arm","docker"],"created_at":"2024-08-01T17:00:35.836Z","updated_at":"2025-04-10T01:30:50.750Z","avatar_url":"https://github.com/ckulka.png","language":"Dockerfile","funding_links":[],"categories":["Dockerfile"],"sub_categories":[],"readme":"# Docker multi-arch example\n\nThis repository demonstrates how to create a multi-arch Docker image supporting multiple platforms, e.g. both `x86_64` and ARM, but building all images on an `x86_64` platform. It is primarily for personal use for reference on how to build manifests and how they work.\n\nThis example also only relies on Docker Hub to build all images, including the ARM variants, and does not rely on separate build servers or environments to build non-amd64 images.\n\nIt's a TL;DR version of the references linked in the README.\n\n## Steps\n\nTo create a multi-arch image, follow the next 4 steps\n\n1. Build and push the image for the `amd64` platform\n2. Build and push the image for the `arm*` platforms\n3. Create the manifest for the multi-arch image\n4. Push the maniest for the multi-arch image\n\n### Automated builds via Docker Hub\n\nThe Docker Hub [Custom build phase hooks](https://docs.docker.com/docker-hub/builds/advanced/#custom-build-phase-hooks) allow in combination with [QEMU](https://www.qemu.org) an entirely automated build of the Docker images via Docker Hub for all major platforms - as it is used in this repository.\n\nTo see how it's done in this repository, see\n\n- Prepare QEMU in a custom build phase hook, [hooks/pre_build](./hooks/pre_build)\n- Dockerfile to build an `arm32v7` image on `x86_64` (Docker Hub), [arm32v7.dockerfile](./arm32v7.dockerfile)\n- Dockerfile to build an `arm64v8` image on `x86_64` (Docker Hub), [arm64v8.dockerfile](./arm64v8.dockerfile)\n\nUse the following build rules in Docker Hub for each multi-arch image:\n\n- One build rule per Dockerfile/platform, e.g. `amd64.dockerfile`\n- The _Docker Tag_ indicates the platform, e.g. `amd64`\n- No build rule for the (multi-arch) image tag in the manifest, e.g. `latest`\n\n![Docker Hub Build rules](build-rules.png)\n\nNote that the builds may fail at the beginning until each build rule ran once. This can be because the manifest references images that don't exist yet. Hence, after running all of them, each referenced image exists and the manifest can be pushed succesfully.\n\n### Push multi-arch manifest automatically (Docker Hub)\n\nOnce Docker Hub has published the `amd64` and `arm*` images, Docker Hub executes the `hooks/post_push` script.\n\nThe script downloads the [manifest-tool](https://github.com/estesp/manifest-tool) and pushes the multi-arch manifest `multi-arch-manifest.yaml`, which - simply put - makes `ckulka/multi-arch-example:latest` a list containing references to the various platform variants.\n\nTo see how it's done in this repository, see\n\n- Multi-arch manifest file, [multi-arch-manifest.yaml](./multi-arch-manifest.yaml)\n- Push the multi-arch manifest file in a custom build phase hook, [hooks/post_push](./hooks/post_push)\n\n### Push the multi-arch manifest manually (manifest-tool)\n\nIf you want to push the multi-arch manifest yourself using the manifest-tool, here are the steps:\n\n1. Create the mulit-arch manifest file, e.g. [multi-arch-manifest.yaml](./multi-arch-manifest.yaml)\n2. Download the manifest-tool\n3. Push the manifest using manifest-tool\n\n```bash\n# Download the manifest-tool\ncurl -Lo manifest-tool https://github.com/estesp/manifest-tool/releases/download/v0.9.0/manifest-tool-linux-amd64\nchmod +x manifest-tool\n\n# Push the multi-arch manifest\n./manifest-tool push from-spec multi-arch-manifest.yaml\n\n# On Docker for Mac, see https://github.com/estesp/manifest-tool#sample-usage\n./manifest-tool --username ada --password lovelace push from-spec multi-arch-manifest.yaml\n```\n\nFor more details, see [manifest-tool: Create/Push](https://github.com/estesp/manifest-tool#createpush).\n\n### Push the multi-arch manifest manually (Docker CLI)\n\nIf you want to push the multi-arch manifest yourself using the Docker CLI, here's how.\n\nAs long as the `docker manifest` commands are experimental, enable the experimental mode for the Docker CLI in `~/.docker/config.json` first:\n\n```json\n{\n  \"experimental\": \"enabled\"\n}\n```\n\nNext up, create and publish multi-arch the manifest.\n\n```bash\n# Create and push the manifest\ndocker manifest create ckulka/multi-arch-example:latest ckulka/multi-arch-example:amd64 ckulka/multi-arch-example:arm32v7\ndocker manifest push --purge ckulka/multi-arch-example:latest\n```\n\nThe created manifest acts as a reference for the linked images. The Docker client, when pulling `ckulka/multi-arch-example:latest`, looks up a \"fitting\" image and then uses that one.\n\nThe `--amend` parameters allows adding additional platforms:\n\n```bash\ndocker manifest create --amend ckulka/multi-arch-example:latest ckulka/multi-arch-example:arm64v7\n```\n\nThe `--purge` parameter deletes the local manifest, which allows recreating and subsequently replacing the list:\n\n```bash\n# Release version 1.0 as latest image variant\ndocker manifest create ckulka/multi-arch-example:latest ckulka/multi-arch-example:1.0-amd64 ckulka/multi-arch-example:1.0-arm32v7\ndocker manifest push --purge ckulka/multi-arch-example:latest\n\n# Release version 2.0 as latest image variant\ndocker manifest create ckulka/multi-arch-example:latest ckulka/multi-arch-example:2.0-amd64 ckulka/multi-arch-example:2.0-arm32v7\ndocker manifest push --purge ckulka/multi-arch-example:latest\n```\n\n## Inspecting the result\n\nThe `docker manifest inspect` command shows the image manifest details - for the multi-arch image, it's the list of images it references and their respective platforms:\n\n```bash\ndocker manifest inspect ckulka/multi-arch-example:latest\n```\n\n```json\n{\n  \"schemaVersion\": 2,\n  \"mediaType\": \"application/vnd.docker.distribution.manifest.list.v2+json\",\n  \"manifests\": [\n    {\n      \"mediaType\": \"application/vnd.docker.distribution.manifest.v2+json\",\n      \"size\": 1728,\n      \"digest\": \"sha256:3a859e0c2bdfb60f52b2c805e2cb55260998b3c343d9e2ea04a742d946be1b1e\",\n      \"platform\": {\n        \"architecture\": \"amd64\",\n        \"os\": \"linux\"\n      }\n    },\n    {\n      \"mediaType\": \"application/vnd.docker.distribution.manifest.v2+json\",\n      \"size\": 1728,\n      \"digest\": \"sha256:3ef9264d6e5ad96ad7bac675d40edf265ae838ae6ca60865abed159c8c5124c8\",\n      \"platform\": {\n        \"architecture\": \"arm\",\n        \"os\": \"linux\"\n      }\n    }\n  ]\n}\n```\n\n## Known limitations\n\nBuilding non-x86_64 images on Docker Hub results in images with incorrectly labelled architectures.\n\nFor example, the `arm32v7` image runs on `arm32v7`, but will labelled as `amd64`, because Docker Hub builds the images on `x86_64`. There is a [workaround for it](https://github.com/moby/moby/issues/36552#issuecomment-459927487), but I've not added it here to keep things simple.\n\nThis issue is currently tracked in [moby/moby#36552](https://github.com/moby/moby/issues/36552).\n\n## References\n\n- [Image Manifest V 2, Schema 2](https://docs.docker.com/registry/spec/manifest-v2-2/)\n- [Docker Manifest CLI reference](https://docs.docker.com/edge/engine/reference/commandline/manifest/)\n- [estesp/manifest-tool](https://github.com/estesp/manifest-tool)\n- [Docker Multi-Architecture Images by Davide Mauri](https://medium.com/@mauridb/docker-multi-architecture-images-365a44c26be6)\n- [Support automated ARM builds](https://github.com/docker/hub-feedback/issues/1261)\n- [Custom build phase hooks](https://docs.docker.com/docker-hub/builds/advanced/#custom-build-phase-hooks)\n- [QEMU.org](https://www.qemu.org)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fckulka%2Fdocker-multi-arch-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fckulka%2Fdocker-multi-arch-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fckulka%2Fdocker-multi-arch-example/lists"}