Quickstart: mezd

This guide installs mezd — the Mezite node agent — on a fresh Linux box and joins it to the managed hub you provisioned in the Managed mezhub quickstart. It should take about five minutes once you have the join token in your clipboard.

By the end you will have mezd running as a systemd service (or a Podman container), an online node visible in mezctl nodes ls, and an ALPN tunnel established to your hub.

Running Mezite yourself? The same agent install works against a self-hosted hub — just point MEZITE_AUTH_ADDR and MEZITE_PROXY_ADDR at your own hub instead of the managed hostname.

Prerequisites

  • A Linux host (x86_64 or arm64) with either systemd or Podman
  • Root or sudo on that host
  • A managed hub host (for example acme.hub.mezite.com) and a node-join token from the Managed mezhub quickstart
  • Outbound TCP/443 from the node to your hub host (the agent dials the hub; the hub never dials back)

Step 1: Install the mezd Binary

Grab the latest release for your architecture and drop the binary into /usr/local/bin. See Installation for the canonical download URLs and checksums — the snippet below assumes you have already pulled the tarball for your platform.

Install mezd bash
# After downloading and extracting the release tarball:
sudo mv mezd /usr/local/bin/mezd
sudo chmod +x /usr/local/bin/mezd

mezd --help

Step 2: Configure the Agent

mezd start reads its configuration entirely from environment variables. Drop them into /etc/mezite/agent.env so systemd can load them in the next step. Replace <your-hub-host> and <your-join-token> with the values from the Managed mezhub quickstart.

Create /etc/mezite/agent.env bash
sudo mkdir -p /etc/mezite
sudo tee /etc/mezite/agent.env >/dev/null <<'EOF'
MEZITE_AUTH_ADDR=<your-hub-host>:443
MEZITE_PROXY_ADDR=<your-hub-host>:443
MEZITE_JOIN_TOKEN=<your-join-token>
MEZITE_NODE_NAME=web-01
MEZITE_NODE_LABELS=env=prod,role=web
MEZITE_DATA_DIR=/var/lib/mezite
EOF
sudo chmod 600 /etc/mezite/agent.env

Both MEZITE_AUTH_ADDR and MEZITE_PROXY_ADDR point at the same managed hostname on port 443 — the managed hub multiplexes the gRPC auth service and the tunnel endpoint over a single TLS port using ALPN.

  • MEZITE_NODE_NAME is optional; if unset, the agent uses the machine's hostname.
  • MEZITE_NODE_LABELS is optional and accepts comma-separated key=value pairs that RBAC roles and access requests can target.
  • MEZITE_DATA_DIR defaults to /var/lib/mezite and stores the agent's identity certificates after the initial join — protect it with 0700 if you customise the path.

Step 3: Create the systemd Unit

Write a unit that launches mezd start with the env file from Step 2, then enable and start it.

/etc/systemd/system/mezd.service ini
[Unit]
Description=Mezite node agent
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
EnvironmentFile=/etc/mezite/agent.env
ExecStart=/usr/local/bin/mezd start
Restart=on-failure
RestartSec=5s
StateDirectory=mezite
StateDirectoryMode=0700

[Install]
WantedBy=multi-user.target
Enable and start mezd bash
sudo systemctl daemon-reload
sudo systemctl enable --now mezd
sudo systemctl status mezd --no-pager
A canonical unit file ships in the repo at deploy/systemd/mezd.service as a starting point. Until that file catches up with the current CLI, prefer the inline unit above — it uses mezd start, which is the supported launch command.

Step 4: Verify the Tunnel

Tail the agent's logs and look for the ALPN handshake — that is the moment the agent has a working reverse tunnel to the hub:

Confirm the agent connected bash
sudo journalctl -u mezd -n 50 --no-pager

# Look for a line containing:
# "ALPN tunnel TLS handshake complete"

Then, on the admin machine where you ran the Managed mezhub quickstart (the same shell with MEZITE_AUTH_SERVER and MEZITE_TOKEN set), list nodes and confirm the new host appears as online:

List nodes from the admin machine bash
mezctl \
  --auth-server="$MEZITE_AUTH_SERVER" \
  --token="$MEZITE_TOKEN" \
  nodes ls

# Output (your new node should appear):
# HOSTNAME  TYPE  STATUS  LABELS             VERSION
# web-01    node  online  env=prod,role=web  0.1.0

Alternative: Run mezd in Podman

Prefer containers? Bind-mount the mezd binary you installed in Step 1 into a small base image and pass the same env vars with -e flags. This is the same pattern the production acceptance suite uses, and it keeps you off the systemd path entirely.

Run mezd as a Podman container bash
sudo podman volume create mezd-data

sudo podman run -d \
  --name mezd \
  --restart=on-failure \
  -v /usr/local/bin/mezd:/usr/local/bin/mezd:ro \
  -v mezd-data:/var/lib/mezite \
  -e MEZITE_AUTH_ADDR=<your-hub-host>:443 \
  -e MEZITE_PROXY_ADDR=<your-hub-host>:443 \
  -e MEZITE_JOIN_TOKEN=<your-join-token> \
  -e MEZITE_NODE_NAME=web-01 \
  -e MEZITE_NODE_LABELS=env=prod,role=web \
  -e MEZITE_DATA_DIR=/var/lib/mezite \
  --entrypoint /usr/local/bin/mezd \
  docker.io/library/alpine:3 \
  start

sudo podman logs -f mezd

A standalone mezd container image is not yet published — for now the simplest reproducible path is the bind-mount above. If you build your own image, set its entrypoint to /usr/local/bin/mezd start and skip the -v /usr/local/bin/mezd volume.

The same ALPN tunnel TLS handshake complete log line should appear within a few seconds, and mezctl nodes ls on the admin machine should list the new node as online.


What Just Happened?

  1. The mezd binary landed on your node and was launched as a long-running process — either by systemd or by Podman.
  2. The agent read its hub address, join token, and node identity from environment variables, dialled the hub over TLS, and used ALPN to multiplex the gRPC auth service and the reverse tunnel onto a single port.
  3. The join handshake exchanged the static token for a host certificate signed by your hub's CA; that certificate now lives in MEZITE_DATA_DIR and is what the agent will use to reconnect if it restarts, even after the join token expires.
  4. The reverse tunnel is held open by the agent; the hub proxies SSH sessions back to the node over this connection without needing any inbound port on the node.

Next Steps

Your hub now has a node. The next quickstart installs msh on your laptop and logs in to that node as an end user.

  • Quickstart: msh — log in from your laptop and SSH to the node you just brought online.
  • SSH Access Guide — agentless OpenSSH nodes, bastion mode, and SSH certificate authority details.
  • RBAC Guide — restrict which users can reach which nodes using the labels you set in Step 2.
  • Systemd Deployment — hardening, log rotation, and recommended unit-file overrides for production.