# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview This is a Docker-based MQTT server setup using Eclipse Mosquitto broker with a web-based MQTTUI dashboard. The system provides MQTT messaging on port 1883, WebSocket support on port 9001, and a web dashboard on port 5000. ## Architecture ### Container Stack - **mosquitto**: Eclipse Mosquitto MQTT broker (eclipse-mosquitto:2) - Runs with user-specified UID/GID from .env - Two listeners: MQTT (1883) and WebSocket (9001) - Persistence enabled with data stored in `./data/mosquitto.db` - **mqttui**: Web dashboard (terdia07/mqttui:latest) - Depends on mosquitto service - Database-enabled for message storage (SQLite) - Configurable via environment variables - Stores data in `./mqttui-data/` directory ### Authentication & Authorization - **Dual authentication model**: Supports both anonymous and authenticated users - Anonymous users have limited access to `public/#` and `$SYS/#` topics only (defined in config/acl.conf:6-10) - Authenticated users require username/password stored in `config/passwords.txt` - Six user types defined (config/acl.conf): - `admin`/`joachim`: Full access (readwrite #) - `panel`: Dashboard user with full access - `testuser`: Personal topic access (user/testuser/#) + public topics - `device1`/`device2`: Device-specific write access (devices/deviceX/#) with read-only status - `monitor`: Global read-only access ### Configuration Files - `config/mosquitto.conf`: Main broker configuration (listeners, persistence, auth, logging) - `config/acl.conf`: Access Control Lists defining per-user topic permissions - `config/passwords.txt`: Generated by setup.sh, stores hashed passwords (not in repo) - `.env`: Environment variables for credentials and settings (not in repo, use .env.example) - `mqtt-panel-config.json`: Legacy config file (current setup uses mqttui instead of mqtt-panel) ## Development Commands ### Initial Setup ```bash # Copy environment template and configure credentials cp .env.example .env # Edit .env and set all passwords # Make scripts executable chmod +x setup.sh test-mqtt.sh # Start containers docker-compose up -d # Create MQTT users from .env credentials ./setup.sh ``` ### Container Management ```bash # Start all services docker-compose up -d # View logs docker-compose logs -f # All services docker-compose logs -f mosquitto # Mosquitto only docker-compose logs -f mqttui # MQTTUI only # Restart services docker-compose restart # All docker-compose restart mosquitto # Mosquitto only # Stop and remove containers docker-compose down # Stop and remove including volumes docker-compose down -v ``` ### User Management ```bash # Add/update user password docker exec -it mosquitto mosquitto_passwd -b /mosquitto/config/passwords.txt USERNAME PASSWORD # Delete user docker exec -it mosquitto mosquitto_passwd -D /mosquitto/config/passwords.txt USERNAME # After modifying users or ACL, restart Mosquitto docker-compose restart mosquitto ``` ### Testing & Debugging ```bash # Run test script (sends sample messages to various topics) ./test-mqtt.sh # Publish to public topic (no auth required) docker exec mosquitto mosquitto_pub -h localhost -t "public/test" -m "Hello" # Publish with authentication docker exec mosquitto mosquitto_pub -h localhost -t "sensors/temperature" -m "22.5" -u admin -P admin123 # Subscribe to all topics docker exec mosquitto mosquitto_sub -h localhost -t '#' -v -u admin -P admin123 # Subscribe to public topics only (no auth) docker exec mosquitto mosquitto_sub -h localhost -t 'public/#' -v # Test Mosquitto configuration docker exec mosquitto mosquitto -c /mosquitto/config/mosquitto.conf -v # Access container shell docker exec -it mosquitto sh docker exec -it mqttui sh ``` ## Important Notes ### Security Considerations - `.env` file contains all credentials and MUST NOT be committed (already in .gitignore) - Default passwords in .env.example must be changed for production - Anonymous access is enabled but restricted to `public/#` topics via ACL - All credentials are loaded from .env by setup.sh (lines setup.sh:8-18) - The SECRET_KEY in .env is used by mqttui for session management ### ACL Behavior - ACL rules are evaluated per-user (config/acl.conf) - Anonymous users get explicit rules defined under `user anonymous` - Authenticated users inherit their specific user rules - Pattern `#` is wildcard for all topics, `+` for single-level wildcard - After ACL changes, always restart mosquitto: `docker-compose restart mosquitto` ### MQTTUI Dashboard - The docker-compose.yml uses mqttui (not mqtt-panel as mentioned in README.md) - Dashboard connects to broker using credentials from .env: MQTT_PANEL_USERNAME/PASSWORD - Database storage enabled (DB_PATH=/app/data/mqtt_messages.db) with cleanup after 30 days - Max 10,000 messages retained in database (DB_MAX_MESSAGES) - Widget configuration is managed through mqttui web interface, not mqtt-panel-config.json ### File Permissions - Mosquitto runs as UID:GID specified in .env (default 1000:1000) - Ensure config/, data/, and log/ directories have correct permissions - passwords.txt should be readable by the mosquitto user (chmod 644) ### Persistence - MQTT messages persist in `./data/mosquitto.db` - MQTTUI data stored in `./mqttui-data/mqtt_messages.db` - To completely reset: `docker-compose down -v` and remove data/log directories ## Endpoints - **MQTT**: localhost:1883 - **WebSocket**: ws://localhost:9001 - **Web Dashboard**: http://localhost:5000 ## Common Patterns ### Adding a New User Type 1. Add credentials to .env 2. Update setup.sh to create the user (lines setup.sh:59-86) 3. Add ACL rules in config/acl.conf 4. Run `./setup.sh` to create user 5. Restart mosquitto: `docker-compose restart mosquitto` ### Debugging ACL Issues 1. Enable verbose logging in config/mosquitto.conf (add `log_type all`) 2. Restart mosquitto: `docker-compose restart mosquitto` 3. Check logs: `docker-compose logs -f mosquitto` 4. Look for "DENIED" messages indicating ACL blocks ### Client Integration - Use MQTT port 1883 for native MQTT clients (Python paho-mqtt, etc.) - Use WebSocket port 9001 for browser-based clients - Provide username/password from .env for authenticated topics - Use anonymous connection only for public/* topics