-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Update image build instructions after Builder deprecation, add blog post #3027
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
464cf44
7741a9e
4246c78
927925f
1c16c3e
57ce7fe
5f9c103
53ab004
67d96a0
62a5078
ffe7729
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| --- | ||
| author: Jan Čermák | ||
| authorURL: https://github.com/sairon | ||
| authorImageURL: https://avatars.githubusercontent.com/u/211416?s=96&v=4 | ||
| title: "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](https://github.com/home-assistant/builder) 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 the `build_from` key in `build.yaml` with a `FROM` statement in your `Dockerfile`: | ||
|
|
||
| ```dockerfile | ||
| FROM ghcr.io/home-assistant/base:latest | ||
| ``` | ||
|
|
||
| As the base images are now published as multi-platform manifests, there is usually no need to define per-arch base images anymore. The `build-image` action still supplies `BUILD_ARCH` as a build argument though, so you can use that in your `Dockerfile` if you need to use it in the template for the base image name. | ||
|
|
||
| - **`labels`** - move any custom Docker labels directly into your `Dockerfile` with a `LABEL` statement: | ||
|
|
||
| ```dockerfile | ||
| 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`, and `io.hass.url` labels automatically. The new actions do not infer these values, so add them explicitly via the `labels` input of the `build-image` (or similar) action. | ||
|
|
||
| - **`args`** - move custom build arguments into your `Dockerfile` as `ARG` definitions with default values: | ||
|
|
||
| ```dockerfile | ||
| ARG MY_BUILD_ARG="default-value" | ||
| ``` | ||
|
|
||
| Default values in `ARG` replace what was previously supplied via `build.yaml`'s `args` dictionary. They can still be overridden at build time with `--build-arg` if 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](https://github.com/home-assistant/apps-example/blob/main/.github/workflows/builder.yaml) in our example app repository for a complete working example. Alternatively, use the [individual actions](https://github.com/home-assistant/builder?tab=readme-ov-file#example-workflow) 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: | ||
|
|
||
| ```yaml | ||
| # 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](/docs/apps/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. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,7 +9,6 @@ addon_name/ | |
| translations/ | ||
| en.yaml | ||
| apparmor.txt | ||
| build.yaml | ||
| CHANGELOG.md | ||
| config.yaml | ||
| DOCS.md | ||
|
|
@@ -21,7 +20,7 @@ addon_name/ | |
| ``` | ||
|
|
||
| :::note | ||
| Translation files, `config` and `build` all support `.json`, `.yml` and `.yaml` as the file type. | ||
| Translation files and `config` support `.json`, `.yml` and `.yaml` as the file type. | ||
|
|
||
| To keep it simple all examples use `.yaml` | ||
| ::: | ||
|
|
@@ -58,7 +57,7 @@ then there will be a variable `TARGET` containing `beer` in the environment of y | |
| All apps (formerly known as add-ons) are based on the latest Alpine Linux image. Home Assistant will automatically substitute the right base image based on the machine architecture. Add `tzdata` if you need to run in a different timezone. `tzdata` Is is already added to our base images. | ||
|
|
||
| ```dockerfile | ||
| ARG BUILD_FROM | ||
| ARG BUILD_FROM=ghcr.io/home-assistant/base:latest | ||
| FROM $BUILD_FROM | ||
|
|
||
| # Install requirements for app | ||
|
|
@@ -73,17 +72,15 @@ RUN chmod a+x /run.sh | |
| CMD [ "/run.sh" ] | ||
| ``` | ||
|
|
||
| If you don't use local build on the device or our build script, make sure that the Dockerfile also has a set of labels that include: | ||
| If you are not using Home Assistant GitHub builder actions (see [Publishing your app](/docs/apps/publishing)), make sure that the Dockerfile also has a set of labels that include: | ||
|
|
||
| ```dockerfile | ||
| LABEL \ | ||
| io.hass.version="VERSION" \ | ||
| io.hass.type="addon" \ | ||
| io.hass.arch="armhf|aarch64|i386|amd64" | ||
| io.hass.type="app" \ | ||
| io.hass.arch="aarch64|amd64" | ||
| ``` | ||
|
|
||
| It is possible to use your own base image with `build.yaml` or if you do not need support for automatic multi-arch building you can also use a simple docker `FROM`. You can also suffix the Dockerfile with the specific architecture to use a specific Dockerfile for a particular architecture, i.e. `Dockerfile.amd64`. | ||
|
|
||
| ### Build args | ||
|
|
||
| We support the following build arguments by default: | ||
|
|
@@ -116,11 +113,11 @@ map: | |
| - type: homeassistant_config | ||
| read_only: False | ||
| path: /custom/config/path | ||
| image: repo/{arch}-my-custom-addon | ||
| image: ghcr.io/my-org/my-app | ||
| ``` | ||
|
|
||
| :::note | ||
| Avoid using `config.yaml` as filename in your app for anything other than the app configuration. The Supervisor does a recursively search for `config.yaml` in the app repository. | ||
| Avoid using `config.yaml` as filename in your app for anything other than the app configuration. The Supervisor does recursively search for `config.yaml` in the app repository. | ||
| ::: | ||
|
|
||
| ### Required configuration options | ||
|
|
@@ -131,7 +128,7 @@ Avoid using `config.yaml` as filename in your app for anything other than the ap | |
| | `version` | string | Version of the app. If you are using a docker image with the `image` option, this needs to match the tag of the image that will be used. | ||
| | `slug` | string | Slug of the app. This needs to be unique in the scope of the [repository](/docs/apps/repository) that the app is published in and URI friendly. | | ||
| | `description` | string | Description of the app. | ||
| | `arch` | list | A list of supported architectures: `armhf`, `armv7`, `aarch64`, `amd64`, `i386`. | ||
| | `arch` | list | A list of supported architectures: `aarch64`, `amd64`. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix markdown table pipe style (MD055) Lines 131 and 172 are missing trailing Suggested fix-| `arch` | list | A list of supported architectures: `aarch64`, `amd64`.
+| `arch` | list | A list of supported architectures: `aarch64`, `amd64`. |
-| `image` | string | | For use with container registries. Set this to the generic (multi-arch) image name, e.g. `ghcr.io/my-org/my-app`. The `{arch}` placeholder is still supported as a compatibility fallback for per-architecture image names (e.g. `ghcr.io/my-org/{arch}-my-app`). If you use this option, set the active Docker tag using the `version` option.
+| `image` | string | | For use with container registries. Set this to the generic (multi-arch) image name, e.g. `ghcr.io/my-org/my-app`. The `{arch}` placeholder is still supported as a compatibility fallback for per-architecture image names (e.g. `ghcr.io/my-org/{arch}-my-app`). If you use this option, set the active Docker tag using the `version` option. |Also applies to: 172-172 🧰 Tools🪛 markdownlint-cli2 (0.22.0)[warning] 131-131: Table pipe style (MD055, table-pipe-style) 🤖 Prompt for AI Agents |
||
|
|
||
| ### Optional configuration options | ||
|
|
||
|
|
@@ -172,8 +169,7 @@ Avoid using `config.yaml` as filename in your app for anything other than the ap | |
| | `legacy` | bool | `false` | If the Docker image has no `hass.io` labels, you can enable the legacy mode to use the config data. | ||
| | `options` | dict | | Default options value of the app. | ||
| | `schema` | dict | | Schema for options value of the app. It can be `false` to disable schema validation and options. | ||
| | `image` | string | | For use with Docker Hub and other container registries. This should be set to the name of the image only (E.g, `ghcr.io/home-assistant/{arch}-addon-example`). If you use this option, set the active docker tag using the `version` option. | ||
| | `codenotary` | string | | For use with Codenotary CAS. This is the E-Mail address used to verify your image with Codenotary (E.g, `[email protected]`). This should match the E-Mail address used as the signer in the [app's extended build options](#app-extended-build) | ||
| | `image` | string | | For use with container registries. Set this to the generic (multi-arch) image name, e.g. `ghcr.io/my-org/my-app`. The `{arch}` placeholder is still supported as a compatibility fallback for per-architecture image names (e.g. `ghcr.io/my-org/{arch}-my-app`). If you use this option, set the active Docker tag using the `version` option. | ||
| | `timeout` | integer | 10 | Default 10 (seconds). The timeout to wait until the Docker daemon is done or will be killed. | ||
| | `tmpfs` | bool | `false` | If this is set to `true`, the containers `/tmp` uses tmpfs, a memory file system. | ||
| | `discovery` | list | | A list of services that this app provides for Home Assistant. | ||
|
|
@@ -269,30 +265,11 @@ We support: | |
| - `list(val1|val2|...)` | ||
| - `device` / `device(filter)`: Device filter can be in the following format: `subsystem=TYPE` i.e. `subsystem=tty` for serial devices. | ||
|
|
||
| ## App extended build | ||
|
|
||
| Additional build options for an app are stored in `build.yaml`. This file will be read from our build systems. | ||
| This is only needed if you are not using the default images or need additional things. | ||
|
|
||
| ```yaml | ||
| build_from: | ||
| armhf: mycustom/base-image:latest | ||
| args: | ||
| my_build_arg: xy | ||
| ``` | ||
|
|
||
| | Key | Required | Description | | ||
| | --- | -------- | ----------- | | ||
| | build_from | no | A dictionary with the hardware architecture as the key and the base Docker image as the value. | ||
| | args | no | Allow additional Docker build arguments as a dictionary. | ||
| | labels | no | Allow additional Docker labels as a dictionary. | ||
| | codenotary | no | Enable container signature with codenotary CAS. | ||
| | codenotary.signer | no | Owner signer E-Mail address for this image. | ||
| | codenotary.base_image | no | Verify the base container image. If you use our official images, use `[email protected]` | ||
| :::note | ||
|
|
||
| We provide a set of [base images][docker-base] which should cover a lot of needs. If you don't want to use the Alpine based version or need a specific image tag, feel free to pin this requirement for your build with the `build_from` option. | ||
| Previously, additional build options such as `build_from`, `args`, and `labels` were configured in a separate `build.yaml` file that was read by the legacy builder. This file is no longer used. Base images should be set directly with a `FROM` statement in your `Dockerfile`, labels with a `LABEL` statement, and custom build arguments with `ARG` definitions. See the [builder migration blog post](/blog/2026/04/02/builder-migration) for detailed migration instructions. | ||
|
|
||
| [docker-base]: https://github.com/home-assistant/docker-base | ||
| ::: | ||
|
|
||
| ## App translations | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.