Systemd Deployment

For bare-metal or VM deployments, Mezite ships systemd unit files in the deploy/systemd/ directory of the repository.

mezhub.service

The main server unit runs the combined auth + proxy services. The server is configured from a YAML file (--config), not from environment variables — see Configuration for the full reference.

deploy/systemd/mezhub.service ini
[Unit]
Description=Mezite Server (Auth + Proxy)
After=network-online.target postgresql.service
Wants=network-online.target

[Service]
Type=simple
ExecStart=/usr/local/bin/mezhub --config=/etc/mezite/mezite.yaml
Restart=always
RestartSec=5
LimitNOFILE=65535

NoNewPrivileges=yes
ProtectSystem=strict
ReadWritePaths=/var/lib/mezite
PrivateTmp=yes

[Install]
WantedBy=multi-user.target

The postgresql.service ordering is only relevant if you are using PostgreSQL on the same host. The default database backend is SQLite (zero external dependencies), in which case you can drop the After=postgresql.service line.

mezd.service

The agent unit runs on each SSH node. mezd is configured entirely via environment variables — there is no agent config file. Set the variables in an EnvironmentFile consumed by systemd.

deploy/systemd/mezd.service ini
[Unit]
Description=Mezite Agent
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/usr/local/bin/mezd start
Restart=always
RestartSec=5
LimitNOFILE=65535
EnvironmentFile=/etc/mezite/agent.env

# Note: NoNewPrivileges and ProtectSystem=strict are intentionally omitted.
# The agent needs root privilege transitions for host user provisioning
# (useradd/userdel) and must write to /etc/passwd, /etc/shadow, /etc/group,
# /home/, and /etc/sudoers.d/.
PrivateTmp=yes

[Install]
WantedBy=multi-user.target

Environment File for mezd

Place the agent's environment file at /etc/mezite/agent.env. Required keys: MEZITE_AUTH_ADDR, MEZITE_PROXY_ADDR, and MEZITE_JOIN_TOKEN (only on first start — once the agent has joined and persisted its identity to MEZITE_DATA_DIR, the token is no longer required for reconnects). Keep the agent's data dir separate from the server's (/var/lib/mezd vs /var/lib/mezite) when both run on the same host.

/etc/mezite/agent.env bash
MEZITE_AUTH_ADDR=mezite.example.com:3025
MEZITE_PROXY_ADDR=mezite.example.com:3024
MEZITE_JOIN_TOKEN=<join-token>
MEZITE_DATA_DIR=/var/lib/mezd
MEZITE_NODE_NAME=web-server-01
MEZITE_NODE_LABELS=env=production,role=web

mezite.yaml — minimal mezhub config

A minimal SQLite-backed config that listens on the default ports. See Configuration for every option, and Reverse Proxy for the LB posture.

/etc/mezite/mezite.yaml yaml
cluster_name: my-cluster
data_dir: /var/lib/mezite

database:
  driver: sqlite               # or: postgres
  url: /var/lib/mezite/mezhub.db

auth:
  enabled: true
  listen_addr: 0.0.0.0:3025

proxy:
  enabled: true
  listen_addr: 0.0.0.0:3080
  ssh_listen_addr: 0.0.0.0:3023
  tunnel_listen_addr: 0.0.0.0:3024
  public_addr: mezite.example.com:3080

log:
  level: info
  format: json

Installation

Install and enable services bash
# Copy binaries (output of 'make build' lands in ./bin/)
sudo cp bin/mezhub /usr/local/bin/
sudo cp bin/mezd /usr/local/bin/

# Install unit files from the repository
sudo cp deploy/systemd/mezhub.service /etc/systemd/system/
sudo cp deploy/systemd/mezd.service /etc/systemd/system/

# Create config + data directories
sudo mkdir -p /etc/mezite /var/lib/mezite /var/lib/mezd

# Drop your mezite.yaml and agent.env into /etc/mezite/, then enable
sudo systemctl daemon-reload
sudo systemctl enable --now mezhub
sudo systemctl enable --now mezd

Log Management

View logs with journalctl:

Viewing logs bash
# Follow mezhub logs
journalctl -u mezhub -f

# View agent logs from the last hour
journalctl -u mezd --since "1 hour ago"

# Filter by priority
journalctl -u mezhub -p err