Skip to content
df12 Productions Marrakesh Express Daemon
Docs · Getting Started

Getting started

Build mxd from source, create a user account, choose between the legacy and Wireframe runtimes, and deploy to production — all in one place.

Route map
Getting started

Five-minute quickstart

Build the SQLite variant

mxd requires the Rust toolchain pinned by rust-toolchain.toml. Clone the repository and build the SQLite variant:

terminal
git clone https://github.com/leynos/mxd.git
cd mxd
make sqlite

The default build keeps legacy-networking enabled, so the classic mxd daemon remains part of the operator surface. Runtime selection is documented behaviour, not a packaging accident.

Create a user account

terminal
# The CLI prompts for a password securely (non-echoed).
# For scripted/CI use only: --password <value>
cargo run --bin mxd -- create-user --username alice

Start the daemon

terminal
cargo run --bin mxd -- --bind 0.0.0.0:5500 --database mxd.db

The server prints mxd listening on 0.0.0.0:5500 once the accept loop is running. Login compatibility is currently documented for Hotline 1.8.5, Hotline 1.9, and SynHX with partial status; use the compatibility matrix before assuming broader client parity.

Wireframe server

The mxd-wireframe-server binary runs the new transport runtime. It honours the same configuration surface — flags, env, TOML — and exposes identical admin subcommands.

terminal
make APP=mxd-wireframe-server sqlite
cargo run --bin mxd-wireframe-server -- --bind 0.0.0.0:6600 --database mxd.db

Wireframe-only build: disable default features with cargo build --no-default-features --features "sqlite toml" to omit the legacy mxd binary entirely while keeping the same CLI flags, MXD_* overrides, .mxd.toml defaults, and admin subcommands.

PostgreSQL

Install the unprivileged embedded helper and switch the database URL:

terminal
cargo install --locked pg-embed-setup-unpriv --version 0.5.0
pg_embedded_setup_unpriv
export MXD_DATABASE='postgres://postgres:<db-password>@localhost/mxd'
cargo run --bin mxd -- --database "$MXD_DATABASE"

Running the test suite

terminal
make fmt
make lint
make test

make test exercises SQLite, PostgreSQL (if the helper has been run), and wireframe-only suites. No manual database setup required.

Installation

mxd builds from source. There is no binary distribution yet.

Prerequisites

The Rust toolchain version is pinned by rust-toolchain.toml in the repository root. cargo and make must be on the PATH. Optionally, install pg-embed-setup-unpriv for PostgreSQL-backed tests without a system-level database install.

Rust toolchain

Version pinned via rust-toolchain.toml

Build tools

cargo and make required

PostgreSQL (optional)

Install pg-embed-setup-unpriv for PostgreSQL tests without system database

Building

For SQLite (the default)

terminal
make sqlite

For PostgreSQL

terminal
make postgres

For the Wireframe server

terminal
make APP=mxd-wireframe-server sqlite

Shared operator surface: both mxd and mxd-wireframe-server reuse the same CLI flags, MXD_* environment overrides, .mxd.toml defaults, and admin subcommands such as create-user.

Runtime selection

The legacy-networking Cargo feature is enabled by default. That keeps the classic mxd binary available. Disabling default features changes the produced binaries and selects the Wireframe runtime as the active listener path:

terminal
cargo build --no-default-features --features "sqlite toml"

Feature flags: This command disables all default features and explicitly enables only sqlite and toml. The legacy mxd binary is skipped via required-features, and server::run() invokes the Wireframe runtime instead.

Treat that runtime choice as user-facing behaviour. The repository documents and tests it explicitly with the Wireframe-first suite, rather than leaving it as an incidental build detail.

Deployment

Production deployment strategies for systemd, containers, and socket activation.

systemd

A recommended service unit:

mxd.service
[Unit]
Description=Marrakesh Express Daemon
After=network.target

[Service]
Type=notify
ExecStart=/usr/local/bin/mxd --bind 0.0.0.0:5500 --database /var/lib/mxd/mxd.db
User=mxd
Group=mxd
Restart=on-failure
WatchdogSec=60s

[Install]
WantedBy=multi-user.target

Type=notify means mxd signals readiness to systemd after binding the socket and running migrations. WatchdogSec=60s means mxd sends a heartbeat every 20 seconds; if systemd doesn't hear one for 60 seconds, it restarts the process.

Socket activation is supported. Create a companion .socket unit that listens on port 5500; systemd holds incoming connections in queue during restarts so clients experience a pause, not a refusal.

Containers

The default bind address 0.0.0.0:5500 works inside a container without modification. Mount a volume at the database path for persistence:

terminal
docker run -v /data/mxd:/var/lib/mxd mxd:latest \
  --bind 0.0.0.0:5500 --database /var/lib/mxd/mxd.db

For PostgreSQL, pass the connection string as an environment variable:

terminal
# Pass credentials via env file, not inline.
docker run --env-file mxd.env mxd:latest

Development note: The fuzz harness ships with its own Dockerfile (fuzz/Dockerfile) that includes AFL++ and sanitizers. It is not intended for production use.

Deployment considerations

User isolation

Run mxd as a dedicated unprivileged user. Never run as root. The service unit example above creates an mxd user and group.

Database backups

For SQLite, back up the .db file while the daemon is stopped. For PostgreSQL, use pg_dump with appropriate scheduling.

Network binding

Bind to 0.0.0.0:5500 for external access or 127.0.0.1:5500 for local-only. Use a reverse proxy for TLS termination if required.

Restart policy

Use Restart=on-failure in systemd or equivalent restart policies in container orchestrators to handle transient failures gracefully.