Zyvor · edge fleet control plane
Every site. Still running.
An offline-first control plane for Linux, Kubernetes, containers and virtual machines. The control plane declares what should run. A small fleet-agent pulls that desired state, caches the complete revision locally and keeps reconciling it when the WAN disappears, with no arbitrary remote shell.
QuickstartRead the docsHow it fits
- Apache-2.0
- Keeps reconciling offline
- 4 typed runtime adapters
- No inbound port on the site
- 0 Go dependencies
- v0.3, single-writer
Why Fleet
Remote sites fail in ordinary ways. Each row is something the README says Fleet does about it.
The agent caches the complete desired revision (0600) and keeps reconciling drift locally. Events stay on disk and replay later.
Agents pull. There is no inbound management port and no generic server-triggered shell.
One revision across four typed adapters: systemd, container (Docker or Podman), k3s and opt-in qemu.
Strict wave rollouts with approval, windows, failure budgets, pause, resume, abort, retry and rollback.
Site cordons: the site keeps its last accepted state but is excluded from new rollout plans.
Scoped API tokens (read, sites:write, rollouts:write, admin) stored only as SHA-256 digests, plus HMAC-signed webhooks.
What it does
Control plane (fleetd)
- Embedded console, no CDN
- Email and password with PBKDF2, signed HttpOnly sessions, RBAC
- Enrollment tokens that become independent per-site identities
- Live inventory, dynamic label groups, declarative revisions
- Bounded audit trail without request bodies
- Prometheus
/metrics, single-writer atomic JSON persistence, one binary
Offline-first agent (fleet-agent)
- Pull-based, no inbound management port on the site
- Complete desired revision cached locally
- Local reconciling continues through WAN loss
- Events queue on disk and replay on the next heartbeat
- Per-site bearer identity; the enrollment token is not reused
- No generic server-triggered shell
| Kind | Behavior | Safety boundary |
|---|---|---|
systemd | Start or stop a named unit | Validated unit name; systemctl only |
container | Run, replace or stop Docker or Podman | Declared image, env, ports and args only |
k3s | Atomically maintain a k3s manifest | Validated name; explicit manifest content |
qemu | Start or stop a basic KVM/QEMU VM | Disabled by default; absolute disk path required |
When sync fails, the agent marks the connectivity transition once, the cached revision stays authoritative, adapters keep reconciling drift, and queued events replay when the control plane returns. No control-plane call is needed to keep the last accepted desired state alive.
How it fits together
fleetd serves the web UI, REST API and rollout engine. Agents on each site connect outbound to it. Zyvor OTA devices use the same server for their assignment and event contract.
v0.3 is a serious single-writer release. Transactional HA storage, signed artifacts, agent OTA and air-gap OCI bundles are future milestones and are not present yet. Fleet is not a data or event plane, not general-purpose configuration management and not a cloud-vendor device registry. See the product plan.
Quickstart
Requires Go 1.27 or newer. These are the commands from the README; --demo is not for production.
1. Build
git clone https://github.com/zyvorai/zyvorai-fleet.git
cd zyvorai-fleet
make check && make build2. Start the control plane
export ZYVOR_FLEET_ADMIN_PASSWORD='zyvor-fleet-demo'
export ZYVOR_FLEET_SESSION_SECRET='local-demo-session-secret-change-me-1234567890'
./bin/fleetd --demoOpen http://127.0.0.1:8080 and sign in as admin@zyvor.local with the demo password above.
3. Enroll a site
export ZYVOR_FLEET_ENROLLMENT_TOKEN='zf_enroll_demo-local-only'
./bin/fleet-agent \
--server http://CONTROL_PLANE:8080 \
--name factory-pune-01 \
--region india-west \
--labels class=factory,tier=production4. Or try the Compose demo
docker compose up --buildControl plane plus two simulated sites. For Helm, systemd and the production checklist, see the deployment guide and the guided tutorial.
License
Fleet is free and open source under the Apache License, Version 2.0. Personal, lab and commercial production use at no charge, subject to Apache-2.0: preserve notices and the NOTICE file where required.
Support the project
Free under Apache-2.0. If it helps you, you can donate any amount you like: https://rzp.io/rzp/utwdYh3. A donation is voluntary and supports development and maintenance. It is not a purchase: it buys no support, SLA, features, priority or license, and it is not tax-deductible (Zyvor AI Labs Private Limited is a company, not a charity). Zyvor Enterprise (supported releases, SLAs, a named contact and enterprise features) is separate: sales@zyvor.dev.
Donate any amountLooking for enterprise support? Contact sales