NixOS appliance with a single Go daemon, React 19 UI, and PostgreSQL state. Boot the ISO. Get ZFS, Docker, GitOps, LDAP, HA clustering, and A/B OTA. No middleware. No bloat.
Pools, datasets, RAIDZ1/2/3, mirrors. Native libzfs CGO in production. AES-256-GCM encryption, scrub scheduling, hot-spare management from the UI.
Container management, Compose stack deployment, template library, ephemeral ZFS-clone sandboxes for atomic updates with rollback built in.
Declare your NAS in a Git repo: pools, datasets, shares, stacks, users. Apply from Git. Capture live state back. Drift detected every 5 minutes. Pool destroy always blocked.
Updates write to the inactive boot slot. Health check fires 90s post-boot and auto-reverts on failure. A bad update never permanently takes the system down.
Patroni + etcd for PostgreSQL HA. SCSI-3 Persistent Reservations for hardware-level storage fencing. Keepalived VIP. Rolling OTA upgrades without downtime.
Active Directory, OpenLDAP, FreeIPA. Web UI logins via real-time LDAP bind. Group-to-role mapping. 4 built-in roles, 31 permissions. TOTP 2FA per user account.
SMB with Time Machine support (vfs_fruit). NFS. iSCSI via kernel LIO/nvmet. NVMe-oF over TCP. All managed from the UI with no manual config editing required.
Automated snapshot scheduling with retention policies. ZFS send/receive for off-site replication over SSH. Cloud sync via rclone to S3, B2, GCS, and 40+ providers.
CPU, RAM, disk I/O, network over WebSocket. ZED event dispatch: scrub, resilver, faults, TRIM progress all surface live in the UI the moment they happen.
udev and ZED detect disk add/remove instantly. The daemon auto-imports faulted pools and surfaces vdev replacement suggestions in the dashboard UI.
Web-based file browser with chunked multi-GB uploads, rename, copy, move, delete. POSIX ACL management with recursive apply. Recycle bin included.
SMTP, webhook, and Telegram alerts for ZFS events and threshold breaches. HMAC-SHA256 chained audit log in PostgreSQL. Tamper-evident without an external system.
zfs get used is non-zero. A git push cannot wipe data.
/dev/disk/by-id/ paths required. Short /dev/sdX paths are rejected at state.yaml parse time, before execution.
Reservations survive reboots (APTPL=1). The SAS controller rejects writes from the non-reservation-holder at the hardware level. No BMC required.
PostgreSQL streaming replication. Automatic failover in 10-30s. HAProxy routes to the current primary. The daemon reconnects within seconds.
Floating IP follows the primary. Health-checks the daemon API every 2 seconds. Clients connect to the VIP and never need to know which node is primary.
Update standby, fail over, update the old primary. Both nodes end up on the new version. No client-visible downtime during the rolling upgrade sequence.
| Feature | DPlaneOS | TrueNAS SCALE | OpenMediaVault |
|---|---|---|---|
| Install type | NixOS ISO appliance | Debian-based own OS | Debian plugin layer |
| Web UI framework | React 19 + TypeScript | Angular | PHP / ExtJS |
| ZFS Encryption UI | ✓ Full UI | ~ Partial | ✗ |
| LDAP/AD for Web UI login | ✓ | ~ SMB only | ✗ |
| RBAC | ✓ 4 roles, 31 perms | ✓ | ✗ |
| GitOps / Declarative config | ✓ | ✗ | ✗ |
| A/B OTA with auto-revert | ✓ | ✗ | ✗ |
| HA clustering | ✓ | ~ Enterprise tier | ✗ |
| iSCSI | ✓ | ✓ | ~ Plugin |
| NVMe-oF / TCP | ✓ | ✗ | ✗ |
| Hot-swap + auto-import | ✓ | ✓ | ~ Manual |
| Open source | ✓ AGPLv3 | ~ Mixed | ✓ GPLv2 |
No shell anywhere. Every exec.Command is a named binary with a validated argument slice. Shell metacharacters blocked at the API layer before any command is constructed.
ZFS operations call libzfs.h directly via CGO in the production binary. No subprocess spawned for pool or dataset operations. The exec fallback only activates in CI.
Every state-changing operation appends an HMAC-SHA256 chained row. The key is stored separately from the database. Forgery requires both DB write access AND the key file.
4 roles, 31 permissions enforced at the handler level via permRoute() middleware. System roles are immutable. Role assignments support expiry dates.
Database errors on session lookup reject with HTTP 500. No fallback to permissive mode. Token format + DB lookup + user match are all required before any request proceeds.
Per-user TOTP 2FA. Login issues a pending_totp session restricted to the verify endpoint only. All other routes reject it until the second factor passes.
ProtectSystem=strict makes the NixOS closure read-only from the daemon's view. NoNewPrivileges=true. MemoryMax=1G. Listens on 127.0.0.1:9000 only.
100 requests per minute per source IP, enforced in-process before any handler runs. Returns HTTP 429 and logs a security event on every trigger.
Root filesystem is ephemeral, replaced on every OTA update. All state lives on /persist. A compromised root partition cannot survive a reboot. Data pools are fully independent.