Building Home Assistant

Note

This is a work in progress.

Overview

This page aims to document and track down the complicated build process of Home Assistant and how the similified build-hass works.

I have mostly figured the complicated upstream build process out and am successfully building Home Assistant in Docker containers1.

Upstream docker images

The Home Assistant builds use a series of intertwined Docker images, which are hard to make sense of.

In general they follow this pattern:

  • Each Dockerfile uses a BUILD_FROM build-argument with a default value.
  • The BUILD_FROM value is set in build.yaml for each arch.

The official/standard Docker image for Home Assistant is the result of chaining several Docker images. Following the chain for amd64:

  1. The Dockerfile in home-assistant/core2:

    FROM ghcr.io/home-assistant/amd64-homeassistant-base:${HASS_VERSION}
    

    Defined in build.yaml.

  2. The amd64-homeassistant-base image is in the home-assistant/docker repo3:

    FROM ghcr.io/home-assistant/amd64-base-python:${PYTHON3_VERSION}-alpine${ALPINE_VERSION}
    

    Defined in build.yaml.

  3. The amd64-base-python image is in the home-assistant/docker-base repo4, in the subdirectory python/${PYTHON_VERSION}

    FROM ghcr.io/home-assistant/amd64-base:
    

    Defined in python/${PYTHON_VERSION}/build.yaml. This FROM does not specify a tag, so it defaults to latest.

  4. The amd64-base image is also in the home-assistant/docker-base repo4, but in the alpine/ subdirectory.

    FROM alpine:
    

    Defined in alpine/build.yaml. This is where the chain ends and upstream images are used.

build-hass

In the build-hass repo, I am working on creating a my own Home Assistant builds.

There are currently no changes to Home Assistant itself, only the build process itself with the aim of making easy-to-understand builds producing the the same releases as the official build process does.

Hosting the "brands" image files locally

There is TODO change I want to make to the official builds, namely enabling setting brandsUrl in home-assistant/frontend5 as a runtime configuration option and creating builds of home-assistant/brands6 to be hosted by a regular HTTP server.

It is currently hardcoded to https://brands.home-assistant.io, causing the frontend to make dozens of requests on each load. This is both bad for privacy (though I should note that I do not believe Home Assistant or Nabu Casa to be doing anything nefarious here, defaulting to privacy-first is just good practice) and in case of no internet connection this makes the frontend flaky.

I have not gotten this far yet, and I am currently working on the builds of home-assistant/core.

Using uv (it's fast!)

By switching to using the fantastic uv tool from Astral, the build times are roughly 5x shorter.

Without making any other changes to the build process, the time for a completely fresh build with no existing Docker image layers:

  • Using standard pip: ca 50 minutes
  • Using uv: ca 10 minutes

These aren't proper benchmarks though, only rough numbers from my build server and laptop, both using Intel CPUs (have not tried it on my Apple Silicone M1 yet). This will obviously by different based on things like CPU and bandwidth.

References

1

ben/build-hass, my builds of Home Assistant.