Local installation
Requirements
- Python: 3.12 or higher
- MariaDB/MySQL: 5.7+ or MariaDB 10.3+
- MQTT Broker: Mosquitto, EMQX, or any MQTT 3.1.1 compatible broker
Step-by-step setup
Install Python dependencies
Create a virtual environment to isolate dependencies:Install required packages:
Configure environment variables
Copy the example environment file:Edit
.env to match your infrastructure:.env
Environment variable reference
| Variable | Required | Default | Description |
|---|---|---|---|
DB_HOST | Yes | - | MariaDB/MySQL host address |
DB_PORT | No | 3306 | Database port |
DB_NAME | Yes | - | Database name |
DB_USER | Yes | - | Database username |
DB_PASSWORD | Yes | - | Database password |
LOG_DIR | No | ./log | Directory for error logs (created automatically) |
HTTP_TIMEOUT_SECONDS | No | 10 | Timeout for POST_ENDPOINT HTTP requests |
MQTT_CLIENT_ID | No | mqtt-gateway | MQTT client identifier |
MQTT_KEEPALIVE | No | 60 | MQTT keepalive interval (seconds) |
FLOWS_RELOAD_INTERVAL_SECONDS | No | 600 | How often to reload flows from database |
Initialize the database
The gateway automatically creates tables on first run, but you can verify your database is accessible:Tables created automatically:
mqtt_servers: MQTT broker configurationflows: Flow definitions (topics, actions, schemas)data: Stored message attributes (for STORE_DB flows)
The gateway uses SQLAlchemy’s
create_all() which is idempotent. Running it multiple times is safe.Start the service
Run the gateway:The entry point is simple:On startup, you’ll see:
app.py
- Database connection established (see
src/config.py:22-26for SQLAlchemy URL construction) - Tables created if missing
- Default MQTT broker seeded if none exists (see
src/db.py:20-35) - Flows loaded and subscriptions established
- Message processing begins
Docker installation
Build the image
The included Dockerfile uses Python 3.12 slim as the base:Run the container
- Docker run
- Docker Compose
Run the gateway with environment variables:
Volume mounts
| Host path | Container path | Purpose |
|---|---|---|
$(pwd)/log | /app/log | Persist error logs outside the container |
Logs are written in daily rotating files with format
YYYY-MM-DD.log (e.g., 2026-03-03.log).Docker networking considerations
Example for host-based services:Database schema
The gateway uses three tables, all created automatically:mqtt_servers table
Stores MQTT broker connection details.
src/models.py
On first run, a default broker at
192.168.0.137:1883 is inserted if no enabled broker exists (see src/db.py:20-35).flows table
Defines message processing flows.
src/models.py
STORE_DB: Store payload attributes in thedatatablePOST_ENDPOINT: Forward payload toendpoint_urlvia HTTP POST
data table
Stores message attributes for STORE_DB flows.
src/models.py
Each message creates multiple rows—one per attribute. Group by
last_msg_id to reconstruct the original message.Logging
Error logs are written to the directory specified byLOG_DIR (default: ./log).
- Format:
YYYY-MM-DD.log(e.g.,2026-03-03.log) - Rotation: New file created daily at midnight UTC
- Mode: Append mode during the day
- MQTT connection failures (see
src/mqtt_client.py:66-68) - Payload validation errors (see
src/mqtt_client.py:80-82) - HTTP POST failures for
POST_ENDPOINTflows (seesrc/processor.py:124-129) - Flow reload errors (see
src/mqtt_client.py:122)
Health checks
The gateway does not expose an HTTP health endpoint by default. To monitor the service:- Process monitoring: Check if
python app.pyis running - Database queries: Verify
last_msg_idis incrementing in theflowstable - Log monitoring: Watch for errors in
LOG_DIR
Troubleshooting
Database connection failed
Database connection failed
Symptoms: Service exits with
Fatal error during startup in logsSolutions:- Verify
DB_HOSTis accessible:ping 192.168.0.137 - Test database connectivity:
mysql -h DB_HOST -P DB_PORT -u DB_USER -p - Check firewall rules allow connections to port 3306
- In Docker, ensure network mode allows access to host services
MQTT broker connection failed
MQTT broker connection failed
Symptoms:
MQTT connection failed with reason code in logsSolutions:- Verify an enabled MQTT server exists:
SELECT * FROM mqtt_servers WHERE enabled = 1 - Test broker connectivity:
telnet 192.168.0.137 1883 - Check
usernameandpasswordinmqtt_serversif authentication is required - Verify the broker supports MQTT 3.1.1 (paho-mqtt compatibility)
Messages not being processed
Messages not being processed
Symptoms: Messages published but no data in
data tableSolutions:- Verify flows are enabled:
SELECT * FROM flows WHERE enabled = 1 - Check topic patterns match: The gateway uses
paho.mqtt.client.topic_matches_sub()for wildcard matching - Validate payload structure matches
payload_schema - Check error logs for validation failures
POST_ENDPOINT requests failing
POST_ENDPOINT requests failing
Symptoms: Errors like
Error posting flow X to endpoint Y in logsSolutions:- Verify
endpoint_urlis not NULL in the flow - Test the endpoint manually:
curl -X POST http://endpoint -H "Content-Type: application/json" -d '{"test": "data"}' - Increase
HTTP_TIMEOUT_SECONDSif the endpoint is slow - Check network connectivity from the gateway to the endpoint
Flows not reloading automatically
Flows not reloading automatically
Symptoms: New flows added to database but not subscribedSolutions:
- Wait for
FLOWS_RELOAD_INTERVAL_SECONDS(default: 600 seconds / 10 minutes) - Restart the service to force immediate reload
- Check logs for
Error reloading flowsmessages
Next steps
Configuration
Learn how to configure flows, schemas, and MQTT servers
API reference
Explore the database schema and available flow actions