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 pointMEZITE_AUTH_ADDRandMEZITE_PROXY_ADDRat your own hub instead of the managed hostname.
Prerequisites
- A Linux host (x86_64 or arm64) with either systemd or Podman
- Root or
sudoon 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.
# 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.
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_NAMEis optional; if unset, the agent uses the machine's hostname. -
MEZITE_NODE_LABELSis optional and accepts comma-separatedkey=valuepairs that RBAC roles and access requests can target. -
MEZITE_DATA_DIRdefaults to/var/lib/meziteand stores the agent's identity certificates after the initial join — protect it with0700if 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.
[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 sudo systemctl daemon-reload
sudo systemctl enable --now mezd
sudo systemctl status mezd --no-pager A canonical unit file ships in the repo atdeploy/systemd/mezd.serviceas a starting point. Until that file catches up with the current CLI, prefer the inline unit above — it usesmezd 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:
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:
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.
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?
- The mezd binary landed on your node and was launched as a long-running process — either by systemd or by Podman.
- 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.
- The join handshake exchanged the static token for a host
certificate signed by your hub's CA; that certificate now lives in
MEZITE_DATA_DIRand is what the agent will use to reconnect if it restarts, even after the join token expires. - 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.