Migrate dashboard to esphome-device-builder and build with uv - #63
Merged
Conversation
ESPHome moved its dashboard into the separate `esphome-device-builder` package; install it alongside the `esphome[displays]` compiler and launch `esphome-device-builder /config` (issue #60). It binds 0.0.0.0:6052 and serves /version, so the port, healthcheck, and the entrypoint passthrough model are unchanged. Build: replace the pip wheel-archive stage with a `uv` virtual environment built in the builder stage and copied whole into the slim final stage (PATH=/opt/venv/bin), keeping build tools out of the final image and matching upstream's move to uv. Pin and auto-track both upstream versions: esphome-version.json gains `device_builder_version`, check-esphome-version.yml resolves and bumps both from PyPI, and build-docker-task.yml passes both as build-args. A device_builder_version image label is added; the image tag still tracks the esphome version. Docs: bump version.json to 1.7, add HISTORY.md (full history, template style), and trim the README release notes to the current release plus a link. Verified locally: the amd64 image builds, and as user 1001:100 the dashboard starts, /version is healthy, the ESPHome CLI sanity check passes, and all device-builder state (.device-builder*.json, peer-link key, secrets.yaml, the git version-history tree) is written under /config as the non-root user with no permission errors, with and without a /cache volume.
There was a problem hiding this comment.
Pull request overview
This PR updates the Docker image to follow ESPHome's dashboard split by switching the container entrypoint to esphome-device-builder, and modernizes the build by constructing a self-contained uv virtual environment in the builder stage and copying it into the final image. It also extends version pinning/tracking so both ESPHome and device-builder versions can be resolved and bumped together.
Changes:
- Switch dashboard startup from
esphome dashboard /configtoesphome-device-builder /config. - Build/install ESPHome + device-builder into a
uvvenv in the builder stage and copy it into the slim final stage (no build toolchain in final image). - Track and bump both
esphomeandesphome-device-builderversions viaesphome-version.json+ the scheduled version-check workflow; pass both as Docker build args and label the image accordingly.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
version.json |
Bumps NBGV version floor from 1.6 to 1.7. |
README.md |
Trims release notes to current release and links to full history; updates design notes to mention uv. |
HISTORY.md |
Adds a dedicated release history document for older versions. |
esphome-version.json |
Extends the pin file to include device_builder_version alongside ESPHome version. |
Docker/entrypoint/dashboard.sh |
Launches the new esphome-device-builder dashboard process. |
Docker/Dockerfile |
Switches install strategy to a copied uv virtual environment and adds device-builder version labeling/build args. |
.github/workflows/check-esphome-version.yml |
Resolves and bumps both upstream PyPI versions in a single rolling PR per branch. |
.github/workflows/build-docker-task.yml |
Reads/passes both pinned versions as build args for the Docker build. |
Construct each pip spec with ${VAR:+==$VAR} so passing only one of
ESPHOME_VERSION / DEVICE_BUILDER_VERSION pins that package instead of silently
installing latest for both. Reword the build-arg and version-step comments to
not overstate reproducibility and to cover both pinned versions.
Relocate the License section below all content, convert remaining inline https URLs to reference-style links, and collect every link definition at the bottom sorted alphabetically (relative repo links stay inline).
device-builder does not honor ESPHOME_DASHBOARD_USE_PING; it always uses an mDNS browser with a periodic ping fallback for device state. Drop it from the README config docs, the Compose example, and the devcontainer env.
- Use past tense for the 1.7 'pinned and auto-tracked' changelog bullet - Fix 'Code and pipeline are on GitHub' subject-verb agreement - Convert HISTORY.md list URLs to reference-style with a sorted definition block - Capitalize ESPHome in the esphome-version.json comment
Clarify the AGENTS.md Markdown convention to allow a trailing backslash for intentional hard line breaks (badges, status, license blocks), preferred over trailing whitespace - so reviews stop flagging the explicit form.
…d wording - Capitalize ESPHome in the build-docker comment and the tracker PR body - Split the PyPI version-resolution null-check so the error names which lookup failed - Reword the README build line: image rebuilds on the weekly schedule and on demand (two-phase), not event-driven on release
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #60.
ESPHome split its dashboard into the separate
esphome-device-builderpackage. This installs it alongside theesphome[displays]compiler and launchesesphome-device-builder /config.Changes
Docker/entrypoint/dashboard.shnow runsesphome-device-builder /config. It binds0.0.0.0:6052and serves/version, so the port, healthcheck, and entrypoint passthrough model are unchanged. (Kept this project'sentrypoint/passthrough model rather than upstream'sdashboard-subcommand routing.)uvvirtual environment (uv venv /opt/venv+uv pip install esphome[displays]==$VER esphome-device-builder==$VER) and the slim final stage copies it whole (PATH=/opt/venv/bin). Removes the wheel-archive shuffle, keeps build tools out of the final image, matches upstream's uv move.esphome-version.jsongainsdevice_builder_version;check-esphome-version.ymlresolves/bumps both from PyPI (one rolling PR);build-docker-task.ymlpasses both as build-args; adevice_builder_versionimage label is added. The image tag still tracks the esphome version.version.json→ 1.7; newHISTORY.md(full history, template style); README release notes trimmed to the current release + link; Project Design updated to the uv approach.Verification (local, amd64)
Built the image and ran it as
--user 1001:100:/versionhealthy in ~6s; device-builder boots fully; ESPHome CLI sanity check OK (2026.6.2) via/opt/venv/bin/esphome; binds0.0.0.0:6052./configas uid 1001 with no EACCES / no root-owned files:.device-builder.json(0600),.device-builder-peer-link-key.bin(0600),secrets.yaml, and the git version-history tree./cachevolume (tmpfs/tmp).esphome_version=2026.6.2,device_builder_version=1.0.12,version=1.7.x.actionlint + markdownlint clean.
CI note
This is the first real exercise of the new pipeline: the PR touches
Docker/**,esphome-version.json, andversion.json, sotest-pull-request.ymlruns the amd64-only smoke build (no push). The build-only smoke can't catch runtime issues — covered by the local non-root run above. Full multi-arch publish stays deferred toworkflow_dispatch/the weekly schedule.🤖 Generated with Claude Code