Amazing thread, thank you so much @MizterB!
Iām trying to return to frontend development after some time, Iāve cloned the frontend repo, opened it in VS Code, then I was asked to reopen it in dev container, after a second Iāve tried following the steps (GitHub - home-assistant/frontend: Frontend for Home Assistant), but the first one gives me an error:
vscode ā /workspaces/frontend (fix-selector ā) $ script/setup
ā¤ YN0000: ā Resolution step
ā¤ YN0002: ā @formatjs/intl-locale@npm:2.4.40 doesn't provide @types/node (p4040e), requested by @formatjs/intl-getcanonicallocales
ā¤ YN0002: ā @web/dev-server@npm:0.0.24 doesn't provide rollup (p8cfb8), requested by @rollup/plugin-node-resolve
ā¤ YN0002: ā home-assistant-frontend@workspace:. doesn't provide @egjs/hammerjs (pc1ec5), requested by vis-network
ā¤ YN0002: ā home-assistant-frontend@workspace:. doesn't provide @types/node (p7c56b), requested by @formatjs/intl-getcanonicallocales
ā¤ YN0002: ā home-assistant-frontend@workspace:. doesn't provide component-emitter (pe6728), requested by vis-network
ā¤ YN0002: ā home-assistant-frontend@workspace:. doesn't provide keycharm (p71c12), requested by vis-network
ā¤ YN0002: ā home-assistant-frontend@workspace:. doesn't provide timsort (pc0292), requested by vis-network
ā¤ YN0002: ā home-assistant-frontend@workspace:. doesn't provide uuid (p3a84b), requested by vis-data
ā¤ YN0002: ā home-assistant-frontend@workspace:. doesn't provide uuid (p9d383), requested by vis-network
ā¤ YN0002: ā home-assistant-frontend@workspace:. doesn't provide vis-util (p2581d), requested by vis-data
ā¤ YN0002: ā home-assistant-frontend@workspace:. doesn't provide vis-util (p014f8), requested by vis-network
ā¤ YN0000: ā Some peer dependencies are incorrectly met; run yarn explain peer-requirements <hash> for details, where <hash> is the six-letter p-prefixed code
ā¤ YN0000: ā Completed in 0s 834ms
ā¤ YN0000: ā Fetch step
ā¤ YN0000: ā Completed in 15s 792ms
ā¤ YN0000: ā Link step
ā¤ YN0001: ā Error: EPERM: operation not permitted, chmod '/workspaces/frontend/node_modules/@babel/core/node_modules/json5/lib/cli.js'
ā¤ YN0000: ā Completed in 7m 30s
ā¤ YN0000: Failed with errors in 7m 47s
vscode ā /workspaces/frontend (fix-selector ā) $
especially this one:
Error: EPERM: operation not permitted, chmod '/workspaces/frontend/node_modules/@babel/core/node_modules/json5/lib/cli.js'
when I try to develop gallery and run cd gallery && script/develop_gallery
I get this errors:
./node_modules/.bin/gulp: 1: XSym: not found
./node_modules/.bin/gulp: 2: 0023: not found
./node_modules/.bin/gulp: 3: 687149e66e3e6360895d0ac20c73b31a: not found
./node_modules/.bin/gulp: 4: ../gulp-cli/bin/gulp.js: not found
Iām using Windows 10, VS Code 1.72.0 and Docker 4.7.0
Any ideas what might be wrong?
this is a great post, thanks a lot
I have updated the original post, as many steps (especially for debugging) were extremely out of date.
Hello,
when I debug my custom componentvin dev container if I made a mistake, after fixing it, I have to close VScode and reopen it for my fix to take effect.
Is there a way to make it faster
Thankās
Great post, clear and concise
I created a mount folder for one of my custom components adding something like:
// Custom component
"source=${localEnv:HOME}/dev/ha-netro-watering/custom_components/netro_watering,target=${containerWorkspaceFolder}/config/custom_components/netro_watering,type=bind"
It works as expected - in terms of folder sync - but I cannot ignore it with github in despite the following configuration in .gitignore file
config
Did i miss something ?
Was getting access errors when building the devcontainer using Docker Desktop. Running the container with the privileged flag seemed to solve the issue. Added the following line to devcontainer.json:
"privileged": true,
When mounting folders in custom_components, I had to make sure the config directory already existed in the repo or vscode would get access errors writing the configuration files.
Also git in wsl seems to block the repo as an unsafe repository in the latest versions. Ive seen mention of using the below json entry to fix this but i couldnt get it to work. I currently have to manually mark it safe using the vscode git tab during build.
"postStartCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}",
Also found a way to add Bluetooth support when running the devcontainer on linux. Using this method i was able to run the devcontainer on my HA production server and SHARE the bluetooth adapter with the existing HA instance. Add the following mounts:
"mounts": [
"source=/var/run/dbus,target=/var/run/dbus,type=bind",
"source=/dev,target=/dev,type=bind"
]
I struggle a lot to get it working these days - even though all was great a year ago.
To overcome the git problem, Iāve modified .devcontainer.json
with:
"postCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder} && script/setup",
But the mounts wouldnāt work. The whole config directory seems to be automatically mounted back to my local clone of core
on my Windows machine, but I donāt know how to link my custom components into the right place. If I try this in Windows, it only results in .lnk
links that donāt work in VSCode or the container.
Iām also struggling to get custom_components working. I was able to get the main core devcontainer up and running just fine.
I suspect it might be that Iām running on MacOS, and Docker does some different things there. Every local path I try to mount gets /host_mnt
prepended to it, and of course that means it canāt find the rest of it. Is /host_mnt
is the root of the my git clone of core? Is there no way on MacOS to mount things outside that fs root? Thanks for any help, I am scarcely a VSCode or Docker expert.
Iāve started on custom component development for a side project and I could not get the custom component to work without logs saying it couldnāt be found when I was directly creating the files in the dev container in vs code. As the same files worked on my production server this was infuriating.
Using the mapping example above to map my custom component git repo to the custom_component directory fixed it, I was nearly out of ideas, this also improves the development workflow considerably.
Thanks for the great article.
Hi @MizterB ,
Google pointed me here when searching āhow to develop homeassistant inside a devcontainerā.
Iām trying to develop a new feature into a custom component. I managed to mount it inside the devcontainerā¦ so far so good, itās working well !!
My question is: do you have any experience simulating a binary sensor inside the devcontainer?
To test my changes on my custom integration I need to have some binary sensor and toggle the status as I wish to check the behavior of my codeā¦
thanks in advance!
Go into Settings and create a Toggle helper entity.
thanks @MizterB but my problem is that I really need the sensor to be a binary_sensor. Thatās because Iām testing a change to the Alarmo custom integration which works only with binary sensors.
I ended up solving my issue by creating an MQTT binary_sensor that I can flip using MQTT explorer or mosquitto_pub utility from commandlineā¦
Can you give some hints on using Devcontainer for custom component development only?
For example, do you clone the custom component repo manually inside the HA container (using the terminal) or you do mount the physical folder by using the mounts
in the devcontainer.json
file? With the latter option, I suspect youāre not on Windows, as it slows down the performance?
How do you run the HA task and also keep your git repository synced in VS Code? I would like to only focus on my git repo of the custom component, without the whole HA core fork, if possible. And have access to the linting, of course.
Windows Subsystem for Linux (wsl)
If the code for your custom integration or library is inside of the WSL filesystem, you need to mount that WSL path.
The mount option in the devcontainers.json file uses your windows filesystem.
Use this path in the source section of the mount to get the directory from WSL:
\\\\wsl.localhost\\Ubuntu\\home...
NOTE: The 4 backslahes at the beginning and the 2 backslashes everywhere else ARE REQUIRED. One backslash escapes the other, and windows requires backslashes or it wonāt work.
Providing some updated steps for June 2024
Mostly the same but a few hints to help get others started. With the introduction of uv
the process has become much quicker - but make sure you remember to use uv pip install
and not pip install
within the dev environment now
If you are working on a HACS component, or require external libraries then you should start with pulling those components down to your file system somewhere. Note where as you will need to input below.
To get the DEV container working the simplest way to get thing is to follow steps 1-5 from: Set up development environment | Home Assistant Developer Docs
Once the container is build open devcontainer.json and replace
"postCreateCommand": "script/setup",
with
"postCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder} && script/setup",
You then want to add a mounts
section to the json. Where doesnt matter, as long as it is at the top level of the json. You do not require all the configurations below, delete the ones you dont need. ${localEnv:HOME}
should be your home directory C:\Users\%UserName%
but you can also manually enter any path on your file system
"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",
],
Rebuild the container
If you dont rebuild none of the above will make any difference.
Once rebuilt you should now be able to see the libraries within your VSCode session in the path you defined under mounts
The next thing that is common is utilising custom libraries. I get this working by adding tasks to the tasks.json located within the .vscode
directory
You might also get some info here on how to target remote libraries, but i prefer to map locally Integration manifest | Home Assistant Developer Docs
I use variations of the below and run this Task
instead of Run Home Assistant Core
{
"label": "Run Home Assistant Core (custom)",
"type": "shell",
"command": "uv pip uninstall <libraryname> && uv pip install -e ./config/custom_libraries/<libraryname> && hass -c ./config",
"group": "test",
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": [],
"dependsOn": ["Compile English translations"]
},
What Iām trying to avoid is to download and handle the whole HA core devcontainer to just run and troubleshoot my custom component.
My repo is in āHACS styleā with a requirements.txt
on the root and then a custom_component/domain
subfolder with all the required files of the integration.
I would like, if possible, to have a devcontainer.json
file in the same repo, so I can keep my git commits in VS Code but, at the same time, run a task to launch an HA instance with the integration loaded, installing the requirements and displaying its logs only. Iām not interested in the whole HA core debugging. And, of course, the Python linting with Ruff during save.
Do you think this is something possible?
EDIT: Thereās something similar here, but it seems not updated to the latest versions (for example Python is old and the linting tools are not the suggested ones).
Not sure how to achieve what you are requesting.
But I would suggest strongly sticking with their provided devcontainer.json
, it really is easier once you have your head around the way they want things to run. Understand the linting can be annoying, but the dev experience is much simpler
As a plus, since moving to uv
the container only takes minutes to build.
Yes, but only as long as youāre āoperatingā on the HA Core development in my opinion.
If youāre creating a custom component (integration), if I understand well, you have to:
- Clone the custom component inside a folder on WSL2
- Mount that folder as you suggested with the
mounts:
part of thedevcontainer.json
- After doing that, where do you edit and commit your integration source code? If inside the devcontainer, you wonāt have the git commit details, because thatās the Home Assistant Core repo I forked previously. Isnāt it? So how can I see the commits of my custom component, create branches, etc.?
Maybe I should open another VS Code window with the custom component git folder as root, but there I wonāt have neither the linting nor the task to run Home Assistant to troubleshoot. So should I keep two VS Code windows, one with the HA Core git root (and the mounts) and another non-devcontainer with the custom component sources?
Probably Iām missing something, hence I would like some tips on what might be the best experience (or how others do that). This one doesnāt seem like the best, IMHO.
In the linked French blog article, it seems that they create a custom devcontainer that just runs HA and inherit the linting tools and tasks to just run the instance with the custom component loaded. But it is outdatedā¦
2 VSCode windows can address your concern - just develop and debug in the HA Core one, then open the custom component in another window and do the git management from there.
I understand what you are trying to do - and there are certainly other approaches. If you donāt want to piggyback on the HA Core dev container, my suggestion is look at what other popular custom integrations are doing. For example, check out HACS itself (GitHub - hacs/integration: HACS gives you a powerful UI to handle downloads of all your custom needs.).