Skip to content

Add a self-contained dev stack - #421

Draft
jamesmulcahy wants to merge 5 commits into
NSPManager:develfrom
jamesmulcahy:feat/dev-stack-pr
Draft

jamesmulcahy wants to merge 5 commits into
NSPManager:develfrom
jamesmulcahy:feat/dev-stack-pr

Conversation

@jamesmulcahy

Copy link
Copy Markdown
Contributor

Depends on #420. This branch is built on it, so its first four commits are #420's. Only the last commit, Add a self-contained dev stack, is new here. I'll rebase once #420 merges.

Summary

docker/dev/nspm-dev runs NSPanelManager from the checkout with its own MQTT broker, in a compose project that never touches real panels or a production broker. It's meant for working on the web app and MQTTManager without a separate manager or a copy of a production database.

Service What it is
mosquitto The stack's own MQTT broker, published on a free port (nspm-dev up prints it)
nspm NSPanelManager built from this checkout, on http://localhost:8010
  • Image: the devel target from Docker: build the dev image as its own target, and shrink the build context #420, the same image docker-build_and_run_dev.sh builds. The two share cached layers, and editing the source never rebuilds the image.
  • Database: a fresh database is seeded with MQTT settings pointing at the stack's broker, plus a room. Seeding only fills in missing settings.
  • MQTTManager:
    • It builds on start. An existing build is brought up to date, and a first build runs in the background, so the web UI is up in the meantime.
    • nspm-dev rebuild and nspm-dev watch rebuild and restart it.
  • Volumes: build output, the Conan cache and /data live in volumes, so no root-owned files end up in the checkout. NSPM_CONAN_CACHE can name a shared host directory instead.
  • Ports: nginx forwards the port in the Host header, so saving passes Django's CSRF check on any NSPM_DEV_PORT.

The stack has no panels of its own. Point a panel, or the firmware running under QEMU, at the broker port nspm-dev up prints, and accept it in the web UI as usual. docker/dev/README.md has the commands and settings.

Draft because

A few follow-ups are still to come before this is ready for review:

  • Seed the manager address panels use to reach the stack.
  • Stop the startup build and nspm-dev rebuild from running at the same time.
  • Work around docker compose exec failing on older compose releases.

🤖 Generated with Claude Code

jamesmulcahy and others added 5 commits October 28, 2026 18:13
The dev image was the release image built with IS_DEVEL=yes and no_mqttmanager_build=yes.
It copied web/, MQTTManager/, HMI_files/ and the nginx files in before installing
anything, so editing any of them reinstalled apt, the build tools, nvm/npm and pip on the
next build, although docker-build_and_run_dev.sh mounts all of them over the copies.

docker/Dockerfile now has a runtime-base stage with the packages and the web UI, and two
final stages on top of it:

- devel: the build tools (install_build_tools.sh yes), no source. Built with
  docker build --target devel, which also skips the MQTTManager build stage.
- release: the source and the MQTTManager build. It is the last stage, so a plain
  docker build and the Home Assistant builder still build it.

The release build stage installs the build tools before copying MQTTManager/ in, so a
local rebuild after a source edit reuses that layer too. The IS_DEVEL and
no_mqttmanager_build build arguments are no longer used.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docker-build_and_run_dev.sh passed BUILDTIME="$(date)" to force a fresh clone and
npm run build of the web UI on every dev build. The ui-builder stage now fetches the
commit WEB_UI_REF points at instead, so the clone and build rerun when that commit
changes and come from the cache otherwise.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Compiling in the dev container writes the build into the checkout's MQTTManager/build,
which mounts over /MQTTManager. .dockerignore only left out some CMake files, so the
libraries and binary (about 800 MB of a Debug build) went into the context of every later
image build, and into the release image's build stage, which compiles its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The release image only serves the generated gui.tft files and example.png previews. The
.bmp, .HMI and .xcf sources and the GIMP scripts they are made with are about 610 MB of
the 812 MB in HMI_files/.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docker/dev/nspm-dev runs NSPanelManager from this checkout with its own MQTT broker, in a
compose project that never touches real panels or a production broker:

- The image is the devel target of docker/Dockerfile, the same one
  docker-build_and_run_dev.sh builds, so the two share their cached layers and editing the
  source never rebuilds it.
- A fresh database is seeded with MQTT settings pointing at the stack's broker and a room.
- MQTTManager builds on start: an existing build is brought up to date, and a first build
  runs in the background so the web UI is up meanwhile. `nspm-dev rebuild` and
  `nspm-dev watch` rebuild and restart it.
- Build output, the Conan cache and /data live in volumes, so no root-owned files end up
  in the checkout. NSPM_CONAN_CACHE can name a shared host directory instead.
- nginx forwards the port in the Host header, so saving passes Django's CSRF check on any
  NSPM_DEV_PORT.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant