- Elixir 91%
- JavaScript 7.2%
- Python 0.8%
- CSS 0.5%
- Shell 0.2%
- Other 0.2%
| .devcontainer | ||
| .forgejo/workflows | ||
| config | ||
| deploy/k8s | ||
| docs | ||
| lib/oxidemq | ||
| priv/admin_web | ||
| scripts | ||
| test | ||
| tools | ||
| .dockerignore | ||
| .editorconfig | ||
| .formatter.exs | ||
| .gitignore | ||
| .pre-commit-config.yaml | ||
| .updatarr.yaml | ||
| AGENT.md | ||
| AGENTS.md | ||
| cliff.toml | ||
| Dockerfile | ||
| Justfile | ||
| mix.exs | ||
| mix.lock | ||
| README.md | ||
| renovate.json | ||
OxideMQ
OxideMQ is an Elixir/OTP MQTT broker for MQTT 3.1.1, MQTT 5.0, and MQTT-aware high availability. The project treats the OASIS MQTT specifications as the source of truth and keeps broker behavior behind tests that exercise the actual protocol, session, storage, transport, and cluster boundaries.
Current State
The repository contains a working broker baseline with:
- MQTT packet parsing, encoding, and validation for MQTT 3.1.1 and MQTT 5.0.
- TCP, TLS, WebSocket, and WSS listener support.
- Session lifecycle, duplicate-client fencing, QoS 1 and QoS 2 state, retained messages, will handling, expiry handling, shared subscriptions, user authentication, and ACL authorization.
- Ra-backed distributed state for sessions, retained messages, shared subscriptions, users, and ACLs.
- Kubernetes-native HA manifests for a StatefulSet deployment, Prometheus monitoring, and disaster-recovery backup export.
- An unauthenticated admin HTTP API intended for a private control plane behind the deployment's edge authentication layer.
Repository Map
lib/oxidemq/application.ex OTP application and supervision tree
lib/oxidemq/protocol MQTT packet structs, parser, encoder, validation
lib/oxidemq/session MQTT session and QoS state machines
lib/oxidemq/broker Broker runtime, listeners, routing, auth
lib/oxidemq/store Durable store boundaries and implementations
lib/oxidemq/transport TCP, TLS, WebSocket, and WSS transports
lib/oxidemq/cluster Discovery, shard ownership, Ra-backed state
lib/oxidemq/admin Admin HTTP API and web UI assets
deploy/k8s/production/base Production Kubernetes base manifests
deploy/k8s/monitoring ServiceMonitor, PrometheusRule, Grafana dashboard
docs/specs/mqtt Local MQTT specification archive
docs/testing Conformance and interoperability coverage
test Unit, conformance, integration, and artifact tests
tools Repository maintenance and interop tooling
Development
Use the dev container for Elixir, Erlang, Node, Python, Docker-backed interop tooling, and repository checks:
devcontainer exec --workspace-folder . just fmt-check
devcontainer exec --workspace-folder . just lint
devcontainer exec --workspace-folder . just test
devcontainer exec --workspace-folder . just everything
Focused recipes are available for protocol, conformance, runtime, E2E artifact, and external MQTT interoperability work:
devcontainer exec --workspace-folder . just conformance
devcontainer exec --workspace-folder . just e2e
devcontainer exec --workspace-folder . just interop-fetch
devcontainer exec --workspace-folder . just interop
AGENT.md is the authoritative project workflow for agent-assisted work.
Configuration
Runtime release configuration is parsed by OxideMQ.Config and documented in
docs/configuration.md. Kubernetes HA mode is intentionally low-knob: a
StatefulSet deployment normally sets only the release identity, cookie, MQTT
port, admin port, and OXIDEMQ_DISCOVERY_MODE=statefulset_dns; Ra storage,
distributed stores, MQTT password authentication, ACL authorization,
backpressure defaults, shard ownership, and membership are derived from the
StatefulSet and the node identity.
Connecting
Connection options for the shared deployment:
| Use case | URL / Host | Port | Transport | TLS | WebSocket path | Status |
|---|---|---|---|---|---|---|
| MQTT TCP | mqtt.wuastbude.de |
1883 |
MQTT over TCP | No | n/a | Exposed |
| MQTT TLS | mqtt.wuastbude.de |
8883 |
MQTT over TLS | Yes | n/a | Exposed |
| MQTT WebSocket | mqtt.wuastbude.de |
8083 |
MQTT over WebSocket | No | /mqtt |
Exposed |
| MQTT WSS | mqtt.wuastbude.de |
8084 |
MQTT over secure WebSocket | Yes | /mqtt |
Exposed |
| Admin UI | https://oxidemq.wuastbude.de |
443 |
HTTPS through Traefik | Yes | n/a | Exposed |
MQTT clients must authenticate with username and password. Client IDs may be any non-empty unique value unless the configured user restricts allowed client IDs.
For MQTT Explorer over plain TCP, select mqtt://, set the host to
mqtt.wuastbude.de, set the port to 1883, disable SSL/TLS, and enter the
user credentials. For MQTT over TLS, select mqtts:// or enable SSL/TLS, use
port 8883, and keep the same username/password authentication. A client
configured for TLS or client certificates will not connect to 1883, because
that listener expects raw MQTT packets and does not perform a TLS handshake.
Kubernetes
The production base lives in deploy/k8s/production/base and is designed for a
three-pod StatefulSet with stable network identity, persistent Ra data, health
probes, a PodDisruptionBudget, NetworkPolicy boundaries, and a backup CronJob.
Monitoring artifacts live in deploy/k8s/monitoring:
oxidemq-service-monitor.yamloxidemq-prometheus-rules.yamlgrafana-dashboard-oxidemq.json
Operational procedures are in docs/operations/ha-runbook.md.
Docker Image
The Dockerfile builds an Elixir release in a builder stage and runs it on a
distroless Debian 13 runtime image with only the runtime package set copied in.
The image exposes MQTT on 1883 and the admin HTTP API on 8080.
Documentation
- Configuration reference:
docs/configuration.md - MQTT conformance manifest:
docs/testing/mqtt-conformance-coverage.toml - External interop suites:
docs/testing/external-suites.md - Ra-backed shard state ADR:
docs/architecture/ra-backed-shard-state.md - Custom discovery ADR:
docs/architecture/custom-discovery.md - HA operations runbook:
docs/operations/ha-runbook.md