---
title: "Deploy HiveMQ CE | (Just Updated) MQTT Broker with Login On, TCP + WebSocket, Data Survives Redeploys"
description: "HiveMQ MQTT broker: login required, TCP + WebSocket, data persists"
category: "Storage"
url: https://railway.com/deploy/hivemq-ce-or-just--1
---

# Deploy HiveMQ CE | (Just Updated) MQTT Broker with Login On, TCP + WebSocket, Data Survives Redeploys

HiveMQ MQTT broker: login required, TCP + WebSocket, data persists

**[Deploy HiveMQ CE | (Just Updated) MQTT Broker with Login On, TCP + WebSocket, Data Survives Redeploys on Railway](https://railway.com/template/hivemq-ce-or-just--1)**

Machine-readable deploy manifest (JSON, validated by TemplateCI): https://railway.com/deploy/hivemq-ce-or-just--1/manifest.json

- **Creator:** SuperSlowSloth
- **Category:** Storage

## Template content

### hivemq

- **Image:** ghcr.io/bon5co/hivemq-ce:2026.5@sha256:cae8d2c71c963bb63315544d1931b52a3612dbf02f042dd9a93a50382965b07d
- **Public domain:** Yes

## Documentation

# Deploy and Host HiveMQ CE on Railway

**Built for an LLM agent to deploy and use.** There is no setup step and nothing to fill in: a 32-character broker password is generated at deploy time, anonymous clients are refused, and the contract below lists every address, variable name and the one script that proves it works.

HiveMQ Community Edition is an open-source MQTT broker from HiveMQ. It speaks MQTT 5 and MQTT 3.1.1 over TCP and WebSocket, keeps retained messages and persistent sessions on disk, and is used for IoT telemetry, device command channels and publish-subscribe messaging between services and agents.

## About Hosting HiveMQ CE

This template runs one service, `hivemq`, built from the official `hivemq/hivemq-ce` 2026.5 image, pinned by digest, with one change: the stock image ships an extension that lets any client connect with any credentials, and this one removes it and installs the open-source HiveMQ File RBAC extension instead. The entrypoint writes the broker's user from `MQTT_USERNAME` and `MQTT_PASSWORD` on every boot, so a rotated password takes effect on the next deploy. The data volume is mounted at `/opt/hivemq/data`, so retained messages and sessions survive redeploys. The entrypoint runs as root only long enough to fix the ownership of the root-owned volume, then drops to the broker user and prints the owner it found. The JVM is capped to the container's CPU limit and to 65% of its memory.

MQTT over TCP is exposed on a Railway TCP proxy (port 1883). MQTT over WebSocket is exposed on the public HTTPS domain at `/mqtt` (port 8000). Services in the same project use the private address.

### Agent contract

- Public URL: MQTT over TCP at `MQTT_PUBLIC_HOST:MQTT_PUBLIC_PORT`; MQTT over WebSocket at `MQTT_WEBSOCKET_URL` (`wss://` plus the service's `RAILWAY_PUBLIC_DOMAIN` plus `/mqtt`, subprotocol `mqtt`).
- Private URL: `mqtt://hivemq.railway.internal:1883`, exposed as `MQTT_PRIVATE_URL`.
- Credentials: user `admin` (set in the image; add a `MQTT_USERNAME` variable to the service to use another name), password in the `MQTT_PASSWORD` variable.
- Auth: MQTT username and password in the CONNECT packet. Anonymous clients and wrong passwords are refused. The TCP proxy does not terminate TLS, so use the private URL or the `wss` address for anything sensitive.
- Health: there is no HTTP health path (a TCP proxy and an HTTP healthcheck cannot share a service). Readiness is a successful authenticated MQTT connect.

```bash
# run with MQTT_PUBLIC_HOST, MQTT_PUBLIC_PORT and MQTT_PASSWORD set (MQTT_USERNAME optional, default admin); needs uv
uv run --no-project --with paho-mqtt python -c '
import os, time, paho.mqtt.client as mqtt
def connect(user, pw, cid):
    c = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=cid, protocol=mqtt.MQTTv5)
    if user: c.username_pw_set(user, pw)
    out = {}
    c.on_connect = lambda cl, u, f, rc, p: out.update(rc=str(rc))
    c.on_message = lambda cl, u, m: out.setdefault("got", []).append(m.payload.decode())
    c.connect(os.environ["MQTT_PUBLIC_HOST"], int(os.environ["MQTT_PUBLIC_PORT"]), 30)
    c.loop_start()
    for _ in range(100):
        if "rc" in out: break
        time.sleep(0.2)
    return c, out
a, ra = connect(None, None, "anon")
print("anonymous:", ra.get("rc"))
user = os.environ.get("MQTT_USERNAME", "admin")
b, rb = connect(user, "wrong", "bad")
print("wrong password:", rb.get("rc"))
c, rc = connect(user, os.environ["MQTT_PASSWORD"], "agent")
print("authenticated:", rc.get("rc"))
c.subscribe("agent/check", qos=1); time.sleep(1)
c.publish("agent/check", "hello", qos=1); time.sleep(2)
print("received:", rc.get("got"))
'
```

A fresh deploy prints `anonymous: Bad user name or password`, `wrong password: Not authorized`, `authenticated: Success` and `received: ['hello']`.

## Why Deploy HiveMQ CE on Railway?

Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.

By deploying HiveMQ CE on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.

- **Agent-ready** - generated password, contract block and one working script; no setup step.
- **Closed by default** - the open allow-all extension is removed, so an exposed broker is not an open relay.
- **MQTT over TCP and WebSocket** - devices connect on the TCP proxy, browsers and edge runtimes connect over `wss`.
- **State survives redeploys** - retained messages and persistent sessions live on the attached volume.
- **Right-sized** - the JVM follows the container limits, not the host's core count.

## Common Use Cases

- **IoT telemetry and commands** - sensors, trackers and gateways publish readings and receive commands over MQTT.
- **Message bus between services and agents** - topics and shared state for backend workers and LLM agents.
- **Browser and mobile live updates** - clients subscribe over WebSocket to push notifications.

## Dependencies for HiveMQ CE Hosting

- One Railway volume for the broker data (created by the template).
- A TCP proxy for MQTT clients outside Railway (created by the template).

### Deployment Dependencies

- [HiveMQ documentation](https://docs.hivemq.com/hivemq/latest/user-guide/index.html)
- [Official image](https://hub.docker.com/r/hivemq/hivemq-ce)
- [hivemq/hivemq-community-edition](https://github.com/hivemq/hivemq-community-edition) - upstream project
- [HiveMQ File RBAC extension](https://github.com/hivemq/hivemq-file-rbac-extension) - authentication

### Implementation Details

| Variable | Purpose |
| --- | --- |
| `MQTT_PASSWORD` | Broker password, generated per deploy. |
| `MQTT_PUBLIC_HOST` | TCP proxy host for clients outside Railway. |
| `MQTT_PUBLIC_PORT` | TCP proxy port for clients outside Railway. |
| `MQTT_PRIVATE_URL` | MQTT address on the private network, for services in the same project. |
| `MQTT_WEBSOCKET_URL` | `wss` address for browsers and WebSocket clients. |

The broker user is `admin`. To change it, add a `MQTT_USERNAME` variable to the service (letters, digits, dot, underscore, hyphen) and redeploy.

Reference it from another service with `${{hivemq.MQTT_PRIVATE_URL}}` and `${{hivemq.MQTT_PASSWORD}}`.


## Similar templates

- [RustFS | (Just Updated) S3 Object Store, Public URL and Keys Set](https://railway.com/deploy/rustfs-or-just-updated-s3-object-store-p) — S3-compatible object store, keys and public URL preset, volume kept
- [TimescaleDB](https://railway.com/deploy/timescaledb-railway-template) — A PostgreSQL-based time-series database for analytics on Railway.
- [Garage S3 Storage](https://railway.com/deploy/garage-s3-storage) — Ultra-light S3 server: fast, open-source, plug-and-play.

Open this page in a browser: https://railway.com/deploy/hivemq-ce-or-just--1
