Offline-first edge fleet control plane for Linux, Kubernetes, containers and virtual machines.
Developer toolsGo · ShellGitHub @zyvoraiOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Zyvor Fleet — offline-first edge site control plane
Translation pending
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
Every site. Still running. Offline-first edge fleet 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. Keeps reconciling offline · 4 typed runtime adapters · No inbound port on the site · 0 Go dependencies · Strict wave rollouts 📖 Read the full docs — tutorial, deployment, runtime adapters, and production runbooks. [README 설치·사용 부분 발췌] QuickstartRead the full README ↗
Offline-first edge fleet 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.
Keeps reconciling offline · 4 typed runtime adapters · No inbound port on the site · 0 Go dependencies · Strict wave rollouts
📖 Read the full docs · 🌐 Site — tutorial, deployment, runtime adapters, and production runbooks.
ZYVOR FLEET CONTROL PLANE
UI · API · RBAC · rollouts
│
pull / heartbeat / replay
│
┌───────────────────┼───────────────────┐
│ │ │
Site Pune Site Delhi Site Tokyo
fleet-agent fleet-agent fleet-agent
│ │ │
┌──────┼──────┐ ┌─────┼─────┐ ┌────┼─────┐
systemd container k3s k3s container QEMU systemd GPU
WAN down? Each agent continues from its cached desired revision.
| Release | What landed |
|---|---|
| Unreleased | OTA devices roll out in canary waves instead of a single assignment, pausing when failure, rollback or offline thresholds trip, with a per-device timeline and recovery guidance |
| Unreleased | fleetctl status: logo, site and rollout health, feature rows; fleetctl status json for the raw dashboard |
| Unreleased | HA design doc and a short soak CI harness proving single-writer reconnect under WAN and disk pressure (not multi-writer HA) |
| 0.3.0 | Zyvor OTA contract: /v1/devices/{device_id}/assignment and /events with digest-bound device tokens |
| 0.3.0 | Site cordons, scoped API tokens, HMAC-SHA256 signed webhooks and a bounded mutation audit trail |
| 0.3.0 | State backup/restore drills, make qualify, and Cosign-signed release SHA256SUMS |
Full history: CHANGELOG.md.
| When this happens… | Fleet gives you… |
|---|---|
| The WAN to a plant drops and nobody can say what the site is running | The agent caches the complete desired revision (0600) and keeps reconciling drift locally; events stay on disk and replay later |
| Managing remote sites means opening an inbound port or a remote shell | Pull-based agents with no inbound management port and no generic server-triggered shell |
| Every site mixes systemd services, containers, k3s and the odd VM | One revision across four typed adapters: systemd, container (Docker/Podman), k3s and opt-in qemu |
| A bad change hits every site at once | Strict wave rollouts with approval, windows, failure budgets, pause/resume/abort/retry and rollback |
| A site is being serviced and must not get the next rollout | Site cordons: the site keeps its last accepted state but is excluded from new rollout plans |
| CI needs to drive rollouts without a shared human password | Scoped API tokens (read, sites:write, rollouts:write, admin) stored only as SHA-256 digests, plus HMAC-signed webhooks |
/metrics · single-writer atomic JSON persistence · one fleetd binary0600)| Kind | Behavior | Safety boundary |
|---|---|---|
systemd | Start/stop a named unit | Validated unit name; systemctl only |
container | Run/replace/stop Docker or Podman | Declared image/env/ports/args only |
k3s | Atomically maintain a k3s manifest | Validated name; explicit manifest content |
qemu | Start/stop a basic KVM/QEMU VM | Disabled by default; absolute disk path required |
| Fleet | balena | |
|---|---|---|
| Device OS | The Linux you already run, with fleet-agent installed | balenaOS |
| Workload kinds | systemd, container (Docker/Podman), k3s, opt-in qemu | Containers |
| Control plane | fleetd, self-hosted (systemd, Compose or Helm) | balenaCloud (hosted), or self-hosted openBalena |
| Offline behavior | Cached revision stays authoritative; typed adapters keep reconciling drift; events replay on reconnect | A supervisor on each device runs the current release |
| Rollouts | Strict waves with approval, windows, failure budgets, rollback; OTA devices in canary waves | Release-based container updates |
| License | Apache-2.0 | Apache-2.0 agent and openBalena; balenaCloud is proprietary |
| HA control plane | Not yet — v0.3 is single-writer | Managed (balenaCloud) |
| Choose balena when | Your fleet is containers on balenaOS and you want a managed cloud to run it |
Zyvor Fleet is a small, open-source (Apache-2.0) site lifecycle/desired-state control plane: declare what should run across systemd/container/k3s/QEMU targets, and a small on-site agent keeps reconciling — including fully offline — with no arbitrary remote shell. It is not a data/event plane (that's Nodra), not a general-purpose config management tool, and not a cloud-vendor device registry.
| Zyvor Fleet | balena | Azure IoT Hub Device Mgmt | AWS IoT Device Mgmt | Rancher/Fleet (k8s) | Ansible/SaltStack | |
|---|---|---|---|---|---|---|
| Primary scope | Cross-runtime site desired-state + offline reconciliation | Container fleet + OTA via balenaCloud | Cloud device twin/management | Cloud device fleet indexing/jobs | Kubernetes cluster/app fleet only | Generic config push, no offline reconciliation loop |
| Runtime targets | systemd, container (Docker/Podman), k3s, QEMU/KVM | balenaOS containers only | SDK-built | SDK-built | Kubernetes only | Anything reachable over SSH/agent |
| Offline autonomy | First-class — agent caches the full desired revision | Limited — designed around balenaCloud connectivity | Requires connectivity | Requires connectivity | Requires API server reachability | Push-based; no continuous offline loop |
| Cloud dependency | None required | balenaCloud (proprietary) | Azure IoT Hub | AWS IoT Core | Kubernetes API (self-hostable) | None, but no fleet control plane |
| License | Apache-2.0 | Apache-2.0 agent + proprietary cloud | Proprietary | Proprietary | Apache-2.0 | Open-source core + commercial tiers |
| HA control plane | Not yet — v0.3 is single-writer | Managed | Managed | Managed | Kubernetes-native HA | N/A |
(General characterizations as of writing — verify against each project's own docs.)
New here? docs/FAQ.md · docs/TROUBLESHOOTING.md
Browser
│ HTTPS
▼
┌──────────────────────────────────────────────┐
│ fleetd │
│ embedded web UI · REST API · rollout engine │
│ auth / RBAC · single-writer store │
└──────────────────┬───────────────────────────┘
│ outbound pull from sites
┌─────────┴─────────┐
▼ ▼
fleet-agent fleet-agent
typed adapters typed adapters
v0.3 is deliberately a single-writer control plane. Kubernetes deploys one replica with a ReadWriteOnce volume. HA storage is a later milestone.
See ARCHITECTURE.md and docs/V0.3_OPERATIONS.md.
When sync fails:
No cloud/control-plane call is necessary to keep the last accepted desired state alive.
Requirements: Go 1.27+.
git clone https://github.com/zyvorai/zyvorai-fleet.git
cd zyvorai-fleet
make check && make build
export ZYVOR_FLEET_ADMIN_PASSWORD='zyvor-fleet-demo'
export ZYVOR_FLEET_SESSION_SECRET='local-demo-session-secret-change-me-1234567890'
./bin/fleetd --demo
Open http://127.0.0.1:8080 — [email protected] / zyvor-fleet-demo. Demo enrollment token: zf_enroll_demo-local-only. --demo is not for production.
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=production
fleetctl status # colorful logo; needs a running fleetd
fleetctl status json
fleetctl sites | events | revisions | rollouts | groups | audit | webhooks
fleetctl group-create "Production" env=production,class=factory
fleetctl rollout-plan GROUP_ID
fleetctl site-maintenance SITE_ID on "scheduled service"
fleetctl api-token-create github-ci operator read,rollouts:write
fleetctl enroll-token "Factory install"
Guided walkthrough: docs/TUTORIAL.md.
{
"name": "Factory stack 2026.09",
"notes": "Promote edge API and maintain time sync",
"workloads": [
{"kind": "systemd", "name": "chronyd", "state": "running"},
{
"kind": "container",
"name": "edge-api",
"state": "running",
"image": "ghcr.io/example/edge-api:1.4.0",
"ports": ["8081:8080"]
},
{
"kind": "k3s",
"name": "local-inference",
"state": "running",
"manifest": "apiVersion: apps/v1\nkind: Deployment\n..."
}
]
}
Create the revision in the UI, target sites or a dynamic group, preview the rollout plan, set wave/failure/approval/window policy and start. A strict wave does not advance until every site in the active wave has reported success or failure.
helm upgrade --install zyvor-fleet ./deploy/helm/zyvor-fleet \
--namespace zyvor-fleet --create-namespace \
--set admin.password='CHANGE_ME' \
--set sessionSecret="$(openssl rand -base64 48)"
# Optional in-cluster node agent
helm upgrade --install zyvor-fleet ./deploy/helm/zyvor-fleet \
--namespace zyvor-fleet --create-namespace \
--set admin.password='CHANGE_ME' \
--set sessionSecret="$(openssl rand -base64 48)" \
--set agent.enabled=true \
--set agent.enrollmentToken='YOUR_TOKEN'
Ordinary remote edge boxes: install fleet-agent on the site, not as a DaemonSet. Raw manifests: kubectl apply -k deploy/kubernetes (copy secret.example.yaml first).
Compose demo: docker compose up --build (control plane + two simulated sites).
0600; login throttling; CSP denies third-party scriptsZYVOR_FLEET_ALLOW_QEMU=1)See SECURITY.md.
v0.3 ships site cordons, scoped API tokens, signed webhooks, and a bounded audit trail. Next: signed artifacts, agent OTA, air-gap OCI bundles, enterprise identity, transactional HA storage — docs/PRODUCT_PLAN.md.
| Doc | Topic |
|---|---|
| zyvorai.github.io/zyvorai-fleet | Product docs |
| docs/TUTORIAL.md | Guided first rollout |
| docs/FAQ.md | Licensing, support, readiness |
| docs/DEPLOYMENT.md | Systemd, Compose, Helm |
| docs/RUNTIME_ADAPTERS.md | Workload kinds |
| ARCHITECTURE.md | Protocol and failure model |
| docs/PRODUCTION.md | Production runbook |
| docs/OTA_CONTRACT.md | OTA assignment + events |
| docs/openapi.yaml | REST API |
Social assets: docs/social/.
make check && make test-race && make live-smoke && make qualify
CI: formatting, go vet, race tests, JS syntax, all binaries — plus rollout lifecycle, health gates, rollback/retry, and typed adapter drift.
Maturity (honest): v0.3 is a serious single-writer release. A transactional HA storage adapter is a future milestone (docs/PRODUCT_PLAN.md), alongside signed artifacts, agent OTA, and air-gap OCI bundles — not present yet. Device Agent and OTA contract surfaces are real (see below). Nodra relationship remains architectural — no code integration in this repository today.
Integrations that ship today
-device-agent-url merges namespaced hardware metadata into heartbeats; failure never blocks a heartbeat./v1/devices/{id}/assignment and /events with digest-bound device tokens (docs/OTA_CONTRACT.md).Zyvor already has strong point products. Fleet is the site lifecycle and desired-state layer that connects them.
| Product | Role next to Fleet |
|---|---|
| Device Agent | Ships today: opt-in -device-agent-url merges hardware metadata into Fleet heartbeats |
| Zyvor OTA | Ships today: Fleet serves the OTA device assignment and events contract |
| Nodra | Pairs with Fleet as the optional edge-data plane (architectural; no code integration in this repo) |
| Yard | Ops console whose Fleet connector pulls sites, rollouts and OTA devices (edge-stack suite) |
The wider platform relationships, as Fleet sees them:
| Product | Owns | Fleet relationship |
|---|---|---|
| Nodra | MQTT/HTTP edge ingress, store-and-forward, twins, local routes | Optional edge-data plane |
| Zyvor Relay | Durable operational action/ack/verify workflow | Optional action bus |
| PacketWolf | eBPF network intelligence | Optional network health/policy evidence |
| Argus | Application assurance | Optional post-rollout verification |
| Forge | GPU/inference operations | Optional edge AI plane |
| HyperCluster | Kubernetes cluster lifecycle | Fleet can coordinate site-level promotion |
| IronWolf | Bare-metal lifecycle | Fleet can represent/target the resulting sites |
| Zeus OS / Machina | VM operations | Fleet handles cross-site desired-state rollout |
Fleet intentionally does not reimplement Nodra's device/event data plane or Fabric's private-cloud VM control plane.
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 / NOTICE where required). See NOTICE.
Zyvor Enterprise adds what production teams ask for: supported releases, deployment and upgrade guidance, priority incident triage, a named technical contact and 24x7 critical intake. Plans and terms: docs/SUBSCRIPTION-MODEL.md · Pricing · [email protected].
See SECURITY.md and CONTRIBUTING.md.
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: [email protected].