Migrating app builds to Docker BuildKit
The legacy home-assistant/builder container and the old home-assistant/builder GitHub Action have been retired. We recommend migrating all GitHub workflows and Dockerfiles for apps (formerly add-ons) as described in this post.
What changed and why
The old builder ran every architecture build inside a single privileged Docker-in-Docker container using QEMU emulation. This was slow, required elevated privileges, and those who were already familiar with Docker needed to learn how to use the custom Home Assistant's builder container. The old builder also had unnecessary maintenance overhead. Today, what the builder does can be fully replaced with Docker BuildKit, which is natively supported on GitHub Actions runners and has built-in multi-arch support with QEMU emulation if needed.
For your CI, the replacement is a set of focused composite GitHub Actions that delegate building to the runner's native Docker with Docker BuildKit. Outside the CI, the migration means that your Dockerfile is now the single source of truth for building your app image, and you can use docker build directly to build and test your app locally without needing to use the builder container.
Migration process
The migration has two parts: updating your Dockerfiles and updating your GitHub Actions workflows.
Update Dockerfiles
The new build workflow doesn't use build.yaml anymore. Move the content into your Dockerfile as follows:
-
build_from- replace thebuild_fromkey inbuild.yamlwith aFROMstatement in yourDockerfile:FROM ghcr.io/home-assistant/base:latestAs the base images are now published as multi-platform manifests, there is usually no need to define per-arch base images anymore. The
build-imageaction still suppliesBUILD_ARCHas a build argument though, so you can use that in yourDockerfileif you need to use it in the template for the base image name. -
labels- move any custom Docker labels directly into yourDockerfilewith aLABELstatement:LABEL \
org.opencontainers.image.title="Your awesome app" \
org.opencontainers.image.description="Description of your app." \
org.opencontainers.image.source="https://github.com/your/repo" \
org.opencontainers.image.licenses="Apache License 2.0"If you are creating a custom workflow, note that the legacy builder used to add the
io.hass.type,io.hass.name,io.hass.description, andio.hass.urllabels automatically. The new actions do not infer these values, so add them explicitly via thelabelsinput of thebuild-image(or similar) action. -
args- move custom build arguments into yourDockerfileasARGdefinitions with default values:ARG MY_BUILD_ARG="default-value"Default values in
ARGreplace what was previously supplied viabuild.yaml'sargsdictionary. They can still be overridden at build time with--build-argif needed.
With the content of build.yaml migrated, you can delete the file from your repository.
Update GitHub Actions workflows
Remove any workflow steps using home-assistant/builder@master and replace them with the new composite actions. See the example workflow in our example app repository for a complete working example. Alternatively, use the individual actions in a more custom workflow as needed.
Image naming
The preferred way to reference a published app image is now the generic (multi-arch) name without an architecture prefix:
# config.yaml
image: "ghcr.io/my-org/my-app"
The {arch} placeholder (e.g. ghcr.io/my-org/{arch}-my-app) is still supported as a compatibility fallback, but it's encouraged to use the generic name and let the manifest handle the platform resolution.
Local builds
After updating your Dockerfile, you can use docker build to build the app image directly - you can refer to Local app testing for more details.
Apps built locally by Supervisor
For backward compatibility, Supervisor still reads build.yaml file if it's present and populates the image build arguments with values read from this file. This will produce warnings and eventually be removed in the future, so it's recommended to migrate to the new Dockerfile-based approach as described above.