Skip to content

X[DEPRECATED] Dev setup

Thomas Lovén edited this page Apr 18, 2023 · 1 revision

Here's how I do Home Assistant development using docker-compose

Directory structure

My development root contains:

- config/
  - configuration.yaml
  - custom_components/
  - www/
- core/
  Clone of http://github.com/home-assistant/core
- frontend/
  Clone of http://github.com/home-assistant/frontend
- docker-compose.yml

config/configuration.yaml

This contains a very very basic home assistant configuration:

default_config:
demo:
frontend:
  development_repo: /frontend

docker-compose.yml

This is where the magic happens

version: '3.5'
services:
  frontend:
    image: node
    volumes:
      - ./frontend:/frontend
    working_dir: /frontend
    command: script/develop

  hass:
    image: homeassistant/home-assistant:dev
    volumes:
      - ./core:/usr/src/homeassistant
      - ./frontend:/frontend
      - ./config/configuration.yaml:/config/configuration.yaml
      - ./config/custom_components:/config/custom_components
      - ./config/www:/config/www
    ports:
      - "8123:8123"
    command: |
      bash -c '
      python -m homeassistant --script ensure_config -c /config &&
      python -m homeassistant --script auth -c /config add dev dev &&
      echo "
        {
          \"data\": {
            \"done\": [
              \"user\",
              \"core_config\",
              \"integration\"
            ]
          },
          \"key\": \"onboarding\",
          \"version\": 3
        }
        " > /config/.storage/onboarding &&
      python -m homeassistant -c /config'

So what's all this then? The frontend service is quite simple. It's a node container that mounts the frontend directory and runs the development script in that.

Before first start (and after updating stuff) you probably need to run docker-compose run frontend yarn to install all dependencies. This could take a while.

Note: Always make sure the frontend service has started completely before starting up the hass service. Otherwise hass won't find the frontend, and pull the most recent one from pypi and ignore any changes you do to the frontend code.

The hass service is a bit tricky. First of all, the core and frontend directories are mounted to get the current hass code and compiled frontend (see development_repo setting in configuration.yaml).

Then selected parts of the configuration directory are mounted. By not mounting everything, the input directory is kept clean, and you always have a completely fresh hass installation available.

The problem with this is that you have to redo the onboarding every time the container is restarted, and that's why the long command: is there. What the boot command does is:

  • Make sure there's a complete configuration
  • Add a user with username dev and password dev
  • Write a file to make Home Assistant think the onboarding is complete*
  • launch Home Assistant

*This is not unlikely to break and require tweaking at some point in the future

Note: I use a similar docker-compose service to test my custom lovelace plugins.

Usage

So, to run this. All you need to do is go to the development root directory and run:

$ docker-compose up -d frontend

Wait for the frontend to compile. This takes a loooong time. You can check the progress with

$ docker-compose logs frontend

It's done when you see "[] Build done @ "
Then run:

$ docker-compose up -d hass

Once that's started up, you can go to http://localhost:8123 and log in with dev:dev.

www/ and custom_components/

The www/ and custom_components/ directories in config/ can be used to add functionality to Home Assistant or the frontend as usual. I like to add links to e.g. my plugins while working on them, but note that symlinks will not work. The links have to be hard links.

Ex:

$ ln ~/code/lovelace-card-mod/card-mod.js ./config/www/card-mod.js

A note on git hooks

The frontend repo has a number of git hooks installed. Those require node or will throw an error. If you don't have node installed, you can use the following script, made executable, named node and put somewhere on your PATH.

#!/bin/bash

docker run -i --rm -v $(pwd):/usr/$(pwd) -w /usr/$(pwd) node node $@