furtka-apps/apps/mosquitto/docker-compose.yaml
Daniel Maksymilian Syrnicki 3408e1aad8
All checks were successful
CI / validate (pull_request) Successful in 6s
CI / shellcheck (pull_request) Successful in 13s
feat: add mosquitto + zigbee2mqtt dependency pair
First catalog apps to exercise core 26.17's app-to-app dependency
feature — until now every app was standalone.

- mosquitto: MQTT broker, first dependency *provider*. Mandatory auth;
  per-consumer accounts created by on_install/on_start hooks
  (scripts/provision-client.sh, scripts/ensure-client.sh) that run inside
  the broker container via `docker compose exec`. Provider-side password
  stash so on_start can restore an account after a volume wipe.
- zigbee2mqtt: first dependency *consumer*. `requires` mosquitto; MQTT
  creds wired in from the provisioning hook via ZIGBEE2MQTT_CONFIG_* env.
  Serial coordinator path as a text setting + devices mapping.

Supporting changes:
- Bump vendored furtka_manifest.py (26.10-era -> 26.17) so the validator
  actually validates the `requires` schema instead of ignoring it.
- Document `requires`/hooks in apps/README.md (was undocumented), including
  the three framework gaps building this pair surfaced.
- CI now shellchecks app hook scripts (apps/*/scripts/*.sh), not just
  repo-root scripts/.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 23:45:27 +02:00

39 lines
1.7 KiB
YAML

# Furtka Mosquitto — MQTT broker (dependency provider).
#
# Provider for the app-to-app dependency feature: consumer apps declare
# `requires: [{app: mosquitto, ...}]` and their hooks (which live in this
# folder under ./scripts/) run INSIDE this container via
# `docker compose exec sh -s` to provision a per-consumer MQTT account.
#
# Networking note: Furtka runs each app as its own compose project on its
# own default network, so consumers can't reach this broker by the
# `mosquitto` service name. We publish 1883 on the host instead, and the
# provisioning hook hands the consumer `mqtt://host.docker.internal:1883`
# (the consumer maps host.docker.internal to the docker host-gateway). A
# shared furtka app network would be the cleaner long-term fix; until then
# the host-port bridge is what works across separate compose projects.
#
# The password_file in mosquitto.conf must exist before the broker starts
# or mosquitto refuses to boot, so the command touches an empty one first
# (zero accounts = nobody can connect, which is the correct secure default
# until a consumer is provisioned). mosquitto then reloads the file on
# SIGHUP, which is how the hooks make a freshly-added account live without
# bouncing the broker.
#
# TODO(image-pin): pin to a digest once verified against the upstream
# registry. `2.0` tracks the latest 2.0.x patch — acceptable for the MVP.
services:
mosquitto:
image: eclipse-mosquitto:2.0
restart: unless-stopped
command: sh -c "touch /mosquitto/data/passwd && exec /usr/sbin/mosquitto -c /mosquitto/config/mosquitto.conf"
ports:
- "1883:1883"
volumes:
- ./mosquitto.conf:/mosquitto/config/mosquitto.conf:ro
- furtka_mosquitto_data:/mosquitto/data
volumes:
furtka_mosquitto_data:
external: true