TUTORIAL
Getting started with Zyvor Fleet
This is a hands-on walkthrough: stand up a demo fleet, tour the web console, declare desired state, promote it in a rollout, and see the CLI equivalent of everything you clicked. It complements the terse README quick start rather than replacing it — start here if you want the guided version.
By the end you'll have a running control plane, two enrolled "edge" sites, a revision applied across both, and a working mental model of how Fleet behaves when a site's connection drops.
1. Start a demo fleet¶
The fastest path uses Docker Compose: one command gives you a control plane plus two already-enrolled simulated edge sites, so you're not starting from an empty dashboard.
git clone https://github.com/zyvorai/fleet.git
cd fleet
docker compose up
Wait for the log line confirming the control plane is healthy, then open
http://localhost:8080. The other two containers (edge-a, edge-b)
are real fleet-agent processes enrolling themselves as factory-pune-01
and retail-delhi-07 — give it up to a minute or so (the control plane
needs to report healthy before the agents start, then each enrolls and
sends its first heartbeat) and both should show up as online in the
console.
Prefer to build locally instead of Docker? See the README's
Quick start for the make build + ./bin/fleetd
--demo + manual fleet-agent path — everything below works the same way
either way.
2. Sign in¶
Zyvor Fleet's sign-in is two steps, like signing into an Apple ID: enter your email, then your password.
- Email:
admin@zyvor.local - Continue
- Password:
zyvor-fleet-demo - Check "Remember me on this device" if you want the console to skip straight to the password step next time you load the page.
- Sign In
You'll land on Overview — the fleet topology view, a live map of every enrolled site radiating out from the control plane, plus at-a-glance counts (sites, online, autonomy, running rollouts) and a recent-events feed.
Two things worth knowing about the console itself:
- It defaults to a light theme; the moon/sun icon (top right) switches to a dark theme, which is remembered per browser.
- The sidebar can collapse to icons-only via the chevron at its bottom — useful on a smaller screen.
3. Look at your sites¶
Click Sites. You should see factory-pune-01 and retail-delhi-07,
both online, each showing detected runtimes, CPU/memory, and their current
desired-revision hash (empty for now — you haven't created one yet).
Click Details on either row to open its drawer: architecture, compute, agent version, last-seen time, labels, and workload health once a revision is applied. Admins can delete a site from here (decommissioning it from the fleet); operators and admins can edit a site's name, region, and labels.
Labels matter because they drive dynamic groups — reusable rollout
targets defined by a selector instead of a fixed site list. A selector
matches sites whose labels satisfy every key=value pair you give it
(there's no "or" — a selector holds one value per key). Click New
group, name it "Production", and give it the selector
tier=production — both demo sites carry that label (class is what
differs between them: factory vs. retail), so the group resolves to
both. Try class=factory instead and you'll see it narrow to just
factory-pune-01.
4. Declare desired state (a revision)¶
A revision is the typed desired state you want sites to converge on —
one or more workloads, each with a kind:
| Kind | What it manages |
|---|---|
systemd |
start/stop a named unit |
container |
run/replace/stop a Docker or Podman container |
k3s |
maintain a manifest in the k3s manifests directory |
qemu |
start/stop a basic KVM/QEMU VM (opt-in, disabled by default) |
The README's desired-state example
mixes systemd and container workloads — real for a Linux edge host
with systemctl and Docker/Podman installed, but the demo agents here
don't have either (the container image is intentionally minimal). k3s
is the one kind that only needs filesystem access, so it's what will
actually reconcile to applied in this demo without any extra setup.
docker-compose.yml already points ZYVOR_FLEET_K3S_MANIFEST_DIR at a
writable path for you; if you're running agents locally instead of via
Compose, export that same variable to a writable directory before
starting fleet-agent (the default, /var/lib/rancher/k3s/server/manifests,
needs root).
Go to Rollouts → New revision. Give it a name like Demo stack 2026.09
and paste this into Workloads (JSON):
[
{
"kind": "k3s",
"name": "hello",
"state": "running",
"manifest": "apiVersion: v1\nkind: ConfigMap\nmetadata:\n name: hello\ndata:\n greeting: hello-from-fleet\n"
}
]
Click Create revision. It now appears under Revisions, ready to be promoted — creating a revision doesn't touch any site by itself; a rollout is what actually pushes it.
5. Start a rollout¶
Click Start rollout (or New rollout from Overview). This is where Fleet's safety model lives:
- Revision — pick the one you just created.
- Wave size — how many sites get the new state at once. With only two demo sites, the default of 10 means both go in a single wave; in a real fleet of thousands, a small wave size limits blast radius.
- Pause between waves — a cooldown before the next wave starts, so you have time to notice a problem.
- Maximum failures — the failure budget; a wave stops advancing once this many sites in it have failed.
- Sites / Dynamic group — target explicit checked sites, or point at the "Production" group you made earlier so membership stays live as sites are added or relabeled later.
- Auto rollback — automatically revert to each site's previous revision if the failure budget is exceeded.
- Require admin approval — gate activation behind an explicit approval step (useful for changes that need a second pair of eyes).
Click Preview plan first — it tells you exactly how many sites, how many waves, and how many are currently offline. A rollout still targets offline sites; each one applies the new desired state on its own the next time it successfully syncs (see Offline autonomy below).
Click Create rollout. Watch it on the Rollouts page: wave count, completed-vs-total sites, and a progress bar. Pause/Resume/Abort/Retry/ Rollback controls appear depending on the rollout's current status. Within a few sync cycles both demo sites should show the revision applied in their Sites drawer.
6. Watch it happen in Events¶
Click Events. Enrollment, connectivity, and rollout lifecycle events all land here and stay visible even across a site reconnecting — nothing is lost just because a site was briefly offline.
7. What happens when a site goes offline¶
This is Fleet's core design point, not an edge case. Try it:
docker compose stop edge-a
factory-pune-01 will show as offline in the console once its heartbeat
lapses. It doesn't roll back or drop its workloads — the agent cached the
full revision body locally, and a typed adapter keeps reconciling it
against that cache every cycle with no control-plane round trip required.
On a real Linux edge host running a container-kind workload, this is
what keeps a crashed container restarted even with the WAN down: delete
the container by hand and the agent puts it back within one reconciliation
interval, control plane or no control plane.
Bring it back:
docker compose start edge-a
It reconnects, a controlplane.reconnected event appears, any events it
queued while offline replay, and it picks up anything new you'd rolled
out in the meantime.
8. Manage access (Settings)¶
Click Settings:
- Zyvor integrations — enable/configure Nodra, PacketWolf, and the
other listed integrations (API key + base URL). As of this release these
store configuration only; wiring an integration to actually call out to
it is separate, per-integration work — check
docs/PRODUCT_PLAN.mdfor what's planned here. - Operators — add a user with the minimum role they need
(
viewer/operator/admin), edit their role or reset their password, or remove them. You can't demote or delete your own currently-signed-in account. - Enrollment tokens — create a short-lived, use-limited token for enrolling new sites, or revoke one early.
9. The same workflow from fleetctl¶
Everything above has a CLI equivalent, useful for scripting or CI:
export ZYVOR_FLEET_ADMIN_PASSWORD='zyvor-fleet-demo'
fleetctl status # colorful logo + features
fleetctl status json # raw dashboard JSON
fleetctl sites
fleetctl events
fleetctl revisions
fleetctl rollouts
fleetctl groups
fleetctl group-create "Production" tier=production
fleetctl rollout-plan GROUP_ID
fleetctl rollout-pause ROLLOUT_ID
fleetctl enroll-token "New factory install"
fleetctl logs in fresh on each invocation (--server/--email/
--password, or the ZYVOR_FLEET_* environment variables shown above) —
there's no separate CLI session to manage.
What's next¶
- Deploying for real: docs/DEPLOYMENT.md — systemd, Docker, raw Kubernetes, and Helm, including production hardening notes.
- Runtime adapter details: docs/RUNTIME_ADAPTERS.md
— exactly what each workload
kinddoes and its safety boundary. - Full API reference: docs/openapi.yaml.
- Roadmap: docs/PRODUCT_PLAN.md — what's explicitly planned but not yet built (signed artifacts, agent OTA, air-gapped bundles, OIDC/SAML, and more).
Clean up the demo whenever you're done:
docker compose down -v