Architecture¶
┌──────────────────────────────────────────────────┐
│ sistemo binary (CLI + daemon) │
│ │
│ CLI ──HTTP──▶ Daemon (:7777) ◀── Dashboard │
│ │ │
│ ┌───────┼───────┐ │
│ ▼ ▼ ▼ │
│ Mach 1 Mach 2 Mach 3 │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │netns│ │netns│ │netns│ │
│ │ TAP │ │ TAP │ │ TAP │ │
│ │ FC │ │ FC │ │ FC │ │
│ └──┬──┘ └──┬──┘ └──┬──┘ │
│ └───────┼───────┘ │
│ sistemo0 bridge (10.200.0.1/16) │
│ Machines: 10.200.0.2, .3, .4, ... │
│ │
│ State: SQLite (~/.sistemo/sistemo.db) │
│ Machines: ~/.sistemo/vms/{id}/ │
└──────────────────────────────────────────────────┘
Design principles¶
| Principle | Implementation |
|---|---|
| Single binary | CLI + daemon in one ~15 MB file, zero dependencies beyond Linux + KVM |
| Single machine | Everything runs on one host, no clustering |
| SQLite | State in ~/.sistemo/sistemo.db — machines, volumes, networks, admin credentials, audit history. No Postgres or Redis |
| Firecracker | One process per machine — fast boot, hardware-level isolation via KVM |
| Dashboard | Built-in Svelte web UI at /dashboard/ — manage machines, images, volumes, networks, and terminal from the browser |
| Terminal | xterm.js in the browser, WebSocket to daemon, SSH into the machine |
Data directory¶
All state lives under ~/.sistemo/ (override with --data-dir):
~/.sistemo/
├── sistemo.db # SQLite database (machines, volumes, networks, IPs, port rules, admin credentials, audit history)
├── config.yml # Config file (optional)
├── bin/firecracker # Firecracker binary
├── kernel/vmlinux # Guest kernel
├── ssh/sistemo_key # ED25519 key pair for machine SSH
├── vms/{id}/ # Per-machine directory (rootfs, logs, specs)
├── images/ # Cached rootfs downloads
└── volumes/ # Persistent volumes
Networking¶
A shared Linux bridge (sistemo0, 10.200.0.1/16) connects all machines. Each machine gets a unique IP and runs inside its own network namespace:
- A veth pair connecting the namespace to the
sistemo0bridge - A namespace bridge wiring the veth to a TAP device
- A TAP device for Firecracker's virtual NIC
- A unique IP (10.200.0.2, .3, .4, ...) allocated from SQLite
- SMTP blocked — ports 25, 465, 587 are dropped per-namespace
Machines on the default bridge can communicate with each other. Named networks provide isolation — each named network gets its own bridge (br-<name>), subnet, and NAT rules. An nftables SISTEMO-ISOLATION chain blocks cross-bridge traffic. See Networking and Port expose for details.
Machine lifecycle¶
- Deploy: CLI inserts a record into SQLite, sends create request to daemon
- Create: Daemon copies rootfs, injects SSH key +
/init, creates network namespace, launches Firecracker - Running: Firecracker process runs inside the namespace, SSH is available for terminal/exec
- Stop: Firecracker process is terminated (SIGTERM then SIGKILL), namespace is cleaned up, rootfs is preserved
- Start: New namespace + Firecracker process using the existing rootfs
- Delete: Process killed, namespace cleaned up, machine directory removed
Auto-recovery¶
The daemon runs a reconciler every 30 seconds that:
- Detects dead Firecracker processes (via
kill -0) - Cleans up orphaned network namespaces and port expose rules
- Removes stale machine entries from the in-memory registry
On daemon restart, it rehydrates from disk — scanning ~/.sistemo/vms/ for machines that still have running Firecracker processes. Port expose rules are restored from SQLite.
Security¶
Warning
The daemon runs as root (required for network namespaces and KVM). The API listens on localhost:7777.
- Dashboard authentication — The web dashboard uses JWT-based sessions. On first visit, you create an admin account (username + password). Credentials are stored (bcrypt-hashed) in SQLite
- Localhost bypass (CLI) — API requests from
127.0.0.1or::1skip authentication, so CLI commands work without credentials on the local machine - Remote access — Set the
HOST_API_KEYenvironment variable (env-var only, not in config.yml) if you expose the daemon beyond localhost. Use a reverse proxy with TLS for production - SSH keys — ed25519, auto-generated at
~/.sistemo/ssh/sistemo_key - Machine isolation — Firecracker's KVM + separate network namespaces per machine