This commit is contained in:
Jonas Bengtsson
2026-09-16 06:08:37 +02:00
parent cce6a4960e
commit 8d2c54beae
54 changed files with 8480 additions and 41 deletions
+95
View File
@@ -0,0 +1,95 @@
# MQTT Management Platform — Release 1
Web-based administration for an Eclipse Mosquitto 2.1 broker: management
login/RBAC, MQTT client/group/role management with ACL editing via the
Dynamic Security plugin, and generated + validated broker configuration.
Architecture and scope follow `specification.md` (Release 1, §68.1).
## Stack
```text
mqtt-frontend React (Vite build) served by nginx, proxies /api → backend
mqtt-backend FastAPI: management auth, RBAC, dynsec client, config engine
mosquitto Eclipse Mosquitto 2.1.2 (pinned), dynsec enabled
mosquitto-control control sidecar: validate/activate/reload configs
mqtt-db PostgreSQL (management data only; NOT host-exposed)
```
Networks: `frontend-net` (frontend↔backend) and `backend-net`
(backend↔db↔mosquitto↔control). Only the frontend HTTP port is published.
## Quick start
```bash
cp .env.example .env # then EDIT the change-me values!
docker compose up -d --build
```
Open http://localhost:8080 and sign in with `ADMIN_INITIAL_USERNAME` /
`ADMIN_INITIAL_PASSWORD` from your `.env`.
Bootstrap sequence on first start:
1. PostgreSQL starts; backend creates its schema (or run migrations
explicitly, see below) and seeds the management admin.
2. Mosquitto starts with `mosquitto/bootstrap/mosquitto.conf` on the
internal network; the dynsec plugin seeds its `admin` client from
`MOSQUITTO_DYNSEC_PASSWORD`.
3. Backend connects to dynsec as that admin client — the management
channel is alive.
4. Configuration changes made in the UI are generated from the
PostgreSQL model, validated with `mosquitto --test-config` (via the
control sidecar), deployed atomically, and recorded as a revision.
> **Note for Windows users:** the compose healthcheck for mosquitto and
> the control sidecar rely on Unix facilities (`pid: service:`, POSIX
> shell commands); run the stack with Docker Desktop + WSL2 as usual —
> nothing here assumes a Linux host beyond Docker itself.
## Configuration channels (why this design)
* **Dynamic Security (runtime)** — clients/groups/roles/ACLs change via
the MQTT `$CONTROL/dynamic-security/v1` API. No files involved.
* **Generated mosquitto.conf (rare)** — listeners/global settings are
generated from the DB model and deployed through `mosquitto-control`,
which shares the broker's PID namespace (`pid: "service:mosquitto"`)
to signal reloads. No Docker socket is mounted anywhere (spec §29).
* Mosquitto 2.1's HTTP API is **not** used as a management channel: it
has no authentication and (currently) exposes read-only plugin info.
## Development
Backend (in container):
```bash
docker compose exec mqtt-backend pytest -q # API + generator tests
docker compose exec mqtt-backend ruff check app tests
docker compose exec mqtt-backend alembic upgrade head # explicit migrations
```
Frontend (local dev server with proxy to backend):
```bash
cd frontend && npm install && npm run dev # http://localhost:5173
```
## Repository layout
```text
compose.yaml stack definition (5 services, 2 networks)
.env.example environment template (secrets: edit before use)
mosquitto/bootstrap/ the one file that ships with the deployment
broker-control/ validate / atomic-activate / reload sidecar
backend/ FastAPI app, models, dynsec client, configgen
frontend/ React + Vite SPA served by nginx
```
## Release 1 scope (see specification.md §68.1)
Included: management authentication & RBAC, dynsec clients/groups/roles
with the six ACL types, config generation from the PostgreSQL model,
validation, deployment with revision history.
Not yet (Release 2/3): PKI/certificates, mTLS listeners, diff view,
rollback, ACL simulator, dashboard/$SYS, audit browsing UI, backup.