Repository navigation
Add isolated Home Assistant development environment with Docker Compose - #183
Conversation
|
Read through it: no secrets or plant data, nothing under One question from reading, not running: on Linux the |
|
Thanks @andreacasarin, this is a welcome addition: a throwaway HA that never touches a real plant is exactly what new contributors were missing. And thanks @Apeiv for the read-through. +1 on Apeiv's point, and I'd rather fix it than document Two ways I'd accept, your choice:
Either way, a run on a Linux host (Docker Engine, not Desktop) in the PR's "Tested on" would close it. The rest looks good from my side: localhost only, internal network, no SIP or plant data, nothing in the HACS zip. |
|
That's a good point, thanks @Apeiv! Addressed the Linux ownership feedback using option 2: The command stops/removes the development Compose project, clears Added safety tests plus a disposable Linux Docker Engine lifecycle test covering fresh onboarding, restart persistence, confirmed root-owned state, reset, and fresh onboarding after reset. That lifecycle test ran and passed in both GitHub Actions Python jobs:
|
lollox80
left a comment
There was a problem hiding this comment.
Thanks @andreacasarin, the reset approach and the Linux Engine lifecycle run close the ownership point nicely.
One change before merging: test_dev_compose_linux.py runs inside the required pytest (3.13) and pytest (3.14) jobs, so every PR now pulls the HA image from Docker Hub and starts the stack twice. That adds about 2 minutes per job (4 → 6 min, repeated by the merge queue), and a Docker Hub hiccup or rate limit would fail PRs that don't touch docker/.
Could you give it a docker marker excluded by default (like media and browser in addopts) and run it in its own job only when docker/** changes? If you'd rather keep this PR as is, say so and we'll track it in a follow-up issue instead.
Everything else looks good from my side.
Generated by Claude Code
lollox80
left a comment
There was a problem hiding this comment.
Thanks, this addresses the earlier request well: the docker marker keeps the lifecycle test out of the required pytest jobs (back to ~4 min), and the new workflow is read-only (contents: read, pull_request only, no secrets), path-filtered, time-limited and runs once. Image digests pinned, localhost-only port, internal network, nothing added to the release zip. Looks good.
One thing CI can't show: maintainers also run the default suite on Windows before each PR, and two of the new tests fail there.
tests/test_dev_seed.py:45-46asserts0o700/0o600, but Windows reports0o777/0o666. The repo already has anassert_private_modefixture intests/conftest.pythat skips the check on win32.tests/test_dev_reset.pycreates symlinks (:33-35,:53) without a skip, and the launcher test runsbashwith a fakedocker. Elsewhere we skip whenos.symlinkraisesOSError(seetests/test_ring_log.py).
The simplest fix is a module-level pytestmark = pytest.mark.skipif(sys.platform == "win32", reason="POSIX permissions, symlinks and bash") in both files.
Optional: restrict push in docker-development.yml to branches: [main], so a same-repo branch with an open PR doesn't run the job twice.
With the Windows skips in place this is ready to merge from my side.
|
Thanks, agreed—addressed in The lifecycle test now has a Validation passed:
Both development guides and the documented test commands are updated. |
|
Thanks—addressed in |
lollox80
left a comment
There was a problem hiding this comment.
Thanks @andreacasarin, everything addressed: docker marker out of the required jobs, a separate read-only path-filtered workflow, Windows skips. Approving.
Generated by Claude Code
What and why
Contributors currently have to install the custom integration and manually onboard a Home Assistant instance before trying setup forms or frontend changes. Add
docker/docker-compose.yamland its supporting files underdocker/so./docker/dev.shstarts a separate development instance with automatic onboarding and thedeveloper/developerlogin.The current checkout is mounted read-only. Running the same command after editing code or switching branches recreates the containers while retaining development configuration and the owner account.
HA_DEV_PORTsupports an alternative localhost port.Only a localhost web proxy is published; HA runs on an internal Docker network. No production configuration, QR data or intercom entry is seeded. Bootstrap verifies the integration's initial form without submitting SIP credentials and cancels that flow. Existing entries are retained on subsequent starts.
This contribution includes no SIP transport changes, hardware probes, LAN/media forwarding or firmware/capture material.
Tested on
Docker Desktop on macOS, Docker Compose v5.5.1, pinned Home Assistant 2026.10.1 image. Fresh onboarding and a second start both passed at an alternative localhost port, including owner login, setup-form cancellation and dashboard WebSocket authentication. Verified persistent login/configuration, read-only checkout mount, absence of a configured intercom and absence of an IPv4 default route in HA. A port conflict failed without stopping the existing stack.
Synthetic seed regression tests cover first startup, preservation of credentials/HA storage/user configuration, and restoring a missing template. No live hardware tests, calls or actuator operations were performed. Initial macOS run before the Linux review follow-up (excluding live, media and browser tests): 2313 passed, 1 skipped, 97.11% line/branch coverage.
ruff check ., shell syntax and Compose configuration validation passed.Linux ownership review follow-up
Address the Linux root-owned-state feedback with the accepted cleanup-container approach, retaining the Home Assistant image's normal user/init behavior:
This stops/removes only the selected development Compose project, clears its
.dev-hacontents through a one-shot seed container with networking disabled, and removes the empty directory as the host user. No hostsudois needed. Both language guides explain that reset deletes development credentials/configuration/history and that Linux files may remain root-owned until reset. Symlinked state roots are refused; reset does not follow child symlinks outside its mount.Added reset safety tests and a disposable-checkout Linux Docker Engine lifecycle test in the existing GitHub Actions pytest jobs. The lifecycle test ran and passed, rather than being skipped, on both Python versions: fresh onboarding, restart persistence, confirmed root-owned state, reset, fresh onboarding after reset and final cleanup. Local unit-test runs skip this Docker lifecycle check and do not start containers.
Verified CI run:
The owner's retained local development containers stayed stopped and their state was not reset. Production was not accessed or modified.
Docs
Docs:
docs/DEVELOPMENT.md,docs/DEVELOPMENT.it.md, both READMEs andCONTRIBUTING.md.Changelog
Changelog: Other changes - Start an isolated, automatically onboarded Home Assistant development instance from the current checkout with Docker Compose.