Installing & running
Install a package or build the binaries, start the broker, and run it as a systemd service.
Packages
Each release of mercuriod, the broker, mercurioctl, its administration tool, and recado, the command-line client, has .deb and .rpm packages and a plain .tar.gz for x86_64, aarch64 and armv7 Linux. They need glibc 2.18 or later. Download the ones for your system and install them:
# Debian, Ubuntu, Raspberry Pi OS sudo apt install ./mercuriod_*.deb ./mercurioctl_*.deb ./recado_*.deb # Fedora, RHEL, openSUSE sudo dnf install ./mercuriod-*.rpm ./mercurioctl-*.rpm ./recado-*.rpm
The mercuriod packages install the broker as /usr/bin/mercuriod, the sample configuration as /etc/mercurio/config.toml and the systemd unit, create a mercurio system user and group for the service, and recommend mercurioctl. Members of the group may run mercurioctl on the broker's host. The configuration can hold passwords, so only root and the group may read it (0640 root:mercurio). Edits to the configuration are kept across upgrades. The Debian package enables and starts the service. With the RPM, start it yourself:
sudo systemctl enable --now mercuriod
The service runs as mercurio, so files it reads that aren't readable by everyone, such as TLS keys and password files, must belong to that user or its group:
sudo chown root:mercurio /etc/mercurio/server.key sudo chmod 640 /etc/mercurio/server.key
On armv7, WASM plugins run in wasmtime's interpreter, as its compiler doesn't support 32-bit ARM, so they're slower there.
Building
Mercurio needs a recent stable Rust toolchain. From the repository root:
# Broker, command-line client and libraries cargo build --release # Only the broker cargo build --release --package mercuriod # Or install the binaries into ~/.cargo/bin cargo install --path mercuriod cargo install --path mercurioctl cargo install --path recado
The binaries end up in target/release/: mercuriod, the broker, mercurioctl, its administration tool, and recado, the command-line client.
Running the broker
mercuriod [OPTIONS] mercuriod passwd -f <FILE> -u <USER> [-d] mercuriod dynsec-init -f <FILE> [-u <USER>]
| Option | Meaning | Default |
|---|---|---|
-c, --config <FILE> | Configuration file | /etc/mercurio/config.toml |
-l, --listen <ADDR> | Override the main listen address, such as 0.0.0.0:1883 | from the configuration |
-v, --verbose | Log at debug level | |
--check | Check the configuration and exit; see Checking a configuration |
Without a file at the default path, the broker starts with the defaults: plain MQTT on 127.0.0.1:1883, no authentication, state in memory. A missing file at a path given with -c is an error.
# Defaults mercuriod # Custom configuration, listening on every interface mercuriod -c ./config.toml -l 0.0.0.0:1883 # Debug logging mercuriod -v
Subcommands
| Command | What it does |
|---|---|
mercuriod passwd -f FILE -u USER | Adds a user to a password file, or changes their password. Prompts for the password. |
mercuriod passwd -f FILE -u USER -d | Removes a user. |
mercuriod dynsec-init -f FILE [-u USER] | Creates a dynamic security file with an administrator, admin by default. |
Signals
| Signal | Effect |
|---|---|
SIGTERM, Ctrl+C | Graceful shutdown: every client is sent a DISCONNECT saying the server is shutting down, and the broker waits up to five seconds for connections to close. |
SIGHUP | Rereads password files, ACL files, the dynamic security file, the TLS certificates, keys, CAs and CRLs, and the certificate files of [auth.http], without dropping connections. See reloading. mercurioctl broker reload does the same and reports each file. Received while the broker starts, for example while a standby waits for the database, it reloads once the broker serves. |
A non-zero exit status means the broker failed to start, for example on an unusable TLS certificate or a port already in use, so service managers notice.
Running as a systemd service
A unit file is provided in mercuriod/contrib/mercuriod.service; the packages install it for you. It runs the broker sandboxed as the mercurio user, with /var/lib/mercurio, which suits the SQLite database, and /var/log/mercurio, for a log file, as its only writable directories, and maps systemctl reload to SIGHUP. Files the broker creates are readable by its user only, and it may keep 65536 files open, as each client connection takes one. It also creates /run/mercurio, where the broker serves its admin socket. Without a mercurio user on the system, systemd creates a temporary one for each run.
The unit is Type=notify: the broker tells systemd it is ready once its listeners are bound and it serves, so systemctl start returns, and units ordered after mercuriod start, only then. A PostgreSQL standby becomes ready when it takes over; until then systemctl status shows it standing by, and as that may last indefinitely, the unit sets no start timeout. On systemctl stop the broker reports that it is stopping before it disconnects its clients.
# Binary, configuration and unit sudo cp target/release/mercuriod /usr/bin/ sudo mkdir -p /etc/mercurio sudo cp mercuriod/contrib/config.toml /etc/mercurio/ sudo cp mercuriod/contrib/mercuriod.service /etc/systemd/system/ # Start it now and at boot sudo systemctl daemon-reload sudo systemctl enable --now mercuriod # Status, logs, reload sudo systemctl status mercuriod journalctl -u mercuriod -f sudo systemctl reload mercuriod
The sample configuration lists every option with its default. A minimal production configuration that keeps state on disk and requires passwords:
[server] host = "0.0.0.0" port = 1883 [storage] backend = "sqlite" path = "/var/lib/mercurio/mercurio.db" [auth] enabled = true allow_anonymous = false password_file = "/etc/mercurio/passwd"
sudo mercuriod passwd -f /etc/mercurio/passwd -u alice
Next steps
- Configuration reference for every option.
- Authentication & access to lock the broker down.
- Listeners to add TLS or WebSocket.
- Administration to look at and change the running broker.