Running the service
The installer starts mddb as a user service in ~/mddb, with content in ~/mddb/data. Restart the service after you edit config.toml.
Control the service
Linux uses a systemd user unit:
systemctl --user restart mddb.service
systemctl --user status mddb.service
journalctl --user -u mddb.service -fmacOS uses a launchd agent:
launchctl kickstart -k gui/$(id -u)/com.maruel.mddb
tail -f ~/Library/Logs/mddb/stdout.log ~/Library/Logs/mddb/stderr.logOn Windows, run mddb.exe from the directory that holds data. Stop it with Ctrl+C. mddb shuts down gracefully on interrupt and termination signals.
Pass provider credentials as environment variables
Voice providers read their API keys from the process environment, for example GEMINI_API_KEY. A user service does not inherit the variables of your interactive shell.
On Linux, keep the keys in a private file and reference it from a drop-in. Drop-ins survive reinstalls and updates:
install -m 600 /dev/null ~/.config/mddb/mddb.env
echo 'GEMINI_API_KEY=your-key' >> ~/.config/mddb/mddb.env
mkdir -p ~/.config/systemd/user/mddb.service.d
printf '[Service]\nEnvironmentFile=%%h/.config/mddb/mddb.env\n' > ~/.config/systemd/user/mddb.service.d/env.conf
systemctl --user daemon-reload
systemctl --user restart mddb.serviceOn macOS, add the variable to the agent and reload it:
plist=~/Library/LaunchAgents/com.maruel.mddb.plist
plutil -replace EnvironmentVariables.GEMINI_API_KEY -string 'your-key' "$plist"
launchctl bootout gui/$(id -u)/com.maruel.mddb
launchctl bootstrap gui/$(id -u) "$plist"The installer replaces the plist each time it runs. Add the variable again after you rerun it.
The Linux unit restricts ports and paths
The systemd unit is hardened. It allows writes only to ~/mddb/data, the mddb config and cache directories, and ~/.local/bin. It allows the server to bind only TCP port 8080 and ephemeral ports.
Add a drop-in when you change these defaults:
| Change | Drop-in line |
|---|---|
server.http uses another port, such as 9090 | SocketBindAllow=tcp:9090 |
voice-gateway.webrtc_udp_port is fixed, such as 3480 | SocketBindAllow=udp:3480 |
server.data_dir is outside ~/mddb/data | ReadWritePaths=/srv/mddb/data |
For example:
mkdir -p ~/.config/systemd/user/mddb.service.d
printf '[Service]\nSocketBindAllow=tcp:9090\n' > ~/.config/systemd/user/mddb.service.d/port.conf
systemctl --user daemon-reload
systemctl --user restart mddb.serviceThe unit file shows every restriction.
Updates restart the service
A stable release checks for updates daily. After it installs one, mddb drains HTTP requests, background work, and voice sessions, then restarts. See Installation.
Check health
GET /api/v1/health reports whether the server answers. Reverse proxies can use it as a health check.