Developing Home Assistant Core in a VSCode DevContainer
While the official developer documentation makes some references to VSCode devcontainers, there does not appear to be a comprehensive guide for setting it up to develop and debug HA core. I started documenting the steps that worked well for me, then realized it would be best to share back with the community in a place where it wouldn’t get lost.
I’m suspect that some (much?) of this isn’t best practice or 100% accurate. But I hope that by sharing this, it will encourage others to contribute information about their workflows and we can continue to grow the developer community.
Developing Home Assistant Core in a VSCode Devcontainer
Setting Up the Local Repository
- Ensure that
git
installed on your development wokstation - Visit the Home Assistant Core repository and click Fork.
- Open a terminal and set up your local repository
git clone https://github.com/YOUR_GIT_USERNAME/core.git
cd core
git remote add upstream https://github.com/home-assistant/core.git
- Create a new feature branch that tracks the
dev
branch in
git checkout -b my_dev_branch --track origin/dev
- Open the local repository in VSCode
Configuring HomeAssistant
By default, the devcontainer will create the config
directory inside the container if it doesn’t already exist. Optionally, you can override this by bind mounting a config
directory from your local filesystem, which can be helpful for long-term persistence or swapping in/out different configurations to support development.
To do this, include a list of mounts
inside /.devcontainer/devcontainer.json
:
"mounts": [
// Custom configuration directory
"source=${localEnv:HOME}/path/to/config,target=${containerWorkspaceFolder}/config,type=bind",
]
If these mounts are modified, then the devcontainer must to be rebuilt
- Press
F1
, and enterRemote-Containers: Rebuild Container
See https://code.visualstudio.com/docs/remote/containers-advanced#_adding-another-local-file-mount for more information.
Running HomeAssistant
-
Open the the local repository in VSCode
-
Accept the prompt to “Reopen in Container”
-
Start HA in the container via the menu options:
Terminal | Run Task... | Preview
-
Open HA in a web browser at http://localhost:8123
Keeping Code Up To Date
This is adapted from https://developers.home-assistant.io/docs/development_catching_up
The following commands will keep your local feature branch up-to-date with HomeAssistant’s official dev
branch.
Reminder: upstream
is the official HA repository, origin
is your remote repository that was forked from it
- Switch to a local feature branch
- Pull the latest commits from a HA’s
upstream/dev
branch - Replay the upstream commits to the local branch, then re-apply local changes
- Push the combined commits back to the forked repository on GitHub
git checkout my_dev_branch
git fetch upstream dev
git rebase upstream/dev
git push origin --force
Debugging HomeAssistant
Set up HomeAssistant’s Remote Python Debugger
Add the following to /config/configuration.yaml
:
debugpy:
start: true
wait: true
See https://www.home-assistant.io/integrations/debugpy/ for more information.
Configure the VSCode Debugger
Insert the following debug configurations into /.vscode/launch.json
:
{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
// Example of attaching to local devcontainer
"name": "HomeAssistant: Attach to Local Devcontainer",
"type": "python",
"request": "attach",
"port": 5678,
"host": "localhost",
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "/workspaces/${workspaceFolderBasename}"
}
],
},
{
// For attaching to a remote Production server
// Update host as needed
// HA code is located at /usr/src/homeassistant in a Supervised install
"name": "HomeAssistant: Attach to Remote",
"type": "python",
"request": "attach",
"port": 5678,
"host": "homeassistant.local",
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "/usr/src/homeassistant"
}
],
}
]
}
Start Debugging
- Ensure that the HA devcontainer is running (
Terminal | Run Task... | Preview
) - Switch to the VSCode Debugger view
- Select the appropriate debug configuration from the dropdown
- Start the debugger
Debugging Custom Components and Libraries
When developing custom components or libraries that exist in other local respoitories on your development machine, the easiest way to incorporate these into HomeAssistant is to bind mount those repositories into HA’s config
directory.
To do this, include a list of mounts
inside /.devcontainer/devcontainer.json
, similar to this example:
"mounts": [
// Custom configuration directory
"source=${localEnv:HOME}/path/to/config,target=${containerWorkspaceFolder}/config,type=bind",
// Custom component
"source=${localEnv:HOME}/path/to/custom_repo/custom_components/component_name,target=${containerWorkspaceFolder}/config/custom_components/component_name,type=bind",
// Custom library
"source=${localEnv:HOME}/path/to/custom_repo/custom_libraries/library_name,target=${containerWorkspaceFolder}/config/custom_libraries/library_name,type=bind",
]
Add more bind mounts as needed for your use case.
If these mounts are modified, then the devcontainer must to be rebuilt
- Press
F1
, and enterRemote-Containers: Rebuild Container
Custom Components
Custom components are mounted in the container under config/custom_components
, which is a HomeAssistant standard.
Custom Libraries
Custom libraries are mounted under config/custom_libraries
. Note that custom_libraries
is a personal naming preference, and is not prescribed in the HomeAssistant docs.
In order to develop a custom library, HA needs to be started with a custom variant of the Preview task, which invokes the --skip-pip
argument as described here: https://developers.home-assistant.io/docs/api_lib_index
Add the following to .vscode/tasks.json
// This task should be used when developing in custom_libraries.
// Any time the container is rebuilt, first run the regular Preview task,
// which installs all HA dependencies. Then, swap in the custom_libraries
// by running the following in the terminal:
// `pip uninstall library_name
// `pip install -e ./config/custom_libraries/library_name`
{
"label": "Preview with Custom Libraries",
"type": "shell",
"command": "hass --skip-pip -c ./config",
"group": {
"kind": "test",
"isDefault": true
},
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": []
},
Before starting HA with this modified Preview task, run the normal Preview task, which will install any libraries the via the normal HA boot process.
Terminal | Run Task... | Preview
If overriding a built-in library, go to the terminal and uninstall the built-in one:
pip uninstall library_name
To then enable a custom library, have pip install it from the filesystem. This should be accessible via the bind mount(s) created above.
pip install -e ./config/custom_libraries/library_name
Finally, to ensure that the custom library is used and not automatically overwritten by HomeAssistant at the next boot, stop the ‘normal’ Preview.
Terminal | Terminate Task...
then select Preview
Now, to start HomeAssistant with custom libraries enabled, start the custom preview command created above:
Terminal | Run Task... | Preview with Custom Libraries