v11.6.4 — released 2026-05-24

ZFS-First NAS OS.
Declarative to the Bone.

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.

NixOS 25.11 OpenZFS 2.3 Go + React 19 PostgreSQL 15+ AGPLv3
400+
API Routes
48
UI Pages
80k+
Lines of Code
8
Go Deps (vendored)
Architecture
One Daemon. Everything Orchestrated.
Nginx proxies the edge. dplaned runs at 127.0.0.1:9000. PostgreSQL holds state. ZFS ops go through libzfs CGO in production. No shell invocation anywhere in the codebase.
dplaned runtime
Browser
   nginx :80/:443  static /opt/dplaneos/app/
       └ proxy /api/ /ws/
             dplaned :9000 (127.0.0.1 only)
                 PostgreSQL local or Patroni HA
                 libzfs CGO → ZFS kernel module
                 Docker unix socket
                 Samba systemctl + smbcontrol
                 NFS exportfs
                 ZED socket (real-time events)
                 exec allowlist no shell, no interpolation
  • OS NixOS 25.11. Declarative from bootloader to daemon. Linux 6.6 LTS, OpenZFS 2.3.
  • Backend Go daemon, ~49k lines, libzfs CGO in production. Zero shell invocations anywhere.
  • Database PostgreSQL 15+, WAL replication. Patroni + etcd manages HA failover.
  • Auth bcrypt / LDAP bind, TOTP 2FA, CSRF double-submit, HMAC-SHA256 audit chain.
  • Frontend React 19 + TypeScript + Vite. Pre-built bundle. No Node at runtime.
  • Security Exec allowlist validates every argument individually. No string interpolation.
  • Updates A/B slot OTA. Health check fires 90s post-boot. Auto-reverts on any failure.
Features
Everything a NAS Needs. Nothing It Doesn't.
Built by a homelabber running 33 TB across 60+ services. No paid tier. No upsells. No compromise.
storage

ZFS Management

Pools, datasets, RAIDZ1/2/3, mirrors. Native libzfs CGO in production. AES-256-GCM encryption, scrub scheduling, hot-spare management from the UI.

deployed_code

Docker & Compose

Container management, Compose stack deployment, template library, ephemeral ZFS-clone sandboxes for atomic updates with rollback built in.

account_tree

GitOps (state.yaml)

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.

autorenew

A/B OTA Updates

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.

hub

High Availability

Patroni + etcd for PostgreSQL HA. SCSI-3 Persistent Reservations for hardware-level storage fencing. Keepalived VIP. Rolling OTA upgrades without downtime.

manage_accounts

LDAP & RBAC

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.

share

Sharing Protocols

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.

backup

Snapshots & Replication

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.

monitoring

Real-Time Monitoring

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.

swap_horiz

Hot-Swap Detection

udev and ZED detect disk add/remove instantly. The daemon auto-imports faulted pools and surfaces vdev replacement suggestions in the dashboard UI.

folder_open

File Management

Web-based file browser with chunked multi-GB uploads, rename, copy, move, delete. POSIX ACL management with recursive apply. Recycle bin included.

notifications

Alerts & Audit

SMTP, webhook, and Telegram alerts for ZFS events and threshold breaches. HMAC-SHA256 chained audit log in PostgreSQL. Tamper-evident without an external system.

GitOps
Your NAS as Code.
Declare the shape of your storage in a Git repository. The reconciler closes the gap between declared state and live state automatically, every five minutes.
state.yaml
version: "1"
ignore_extraneous: false

pools:
  - name: tank
    topology:
      data:
        - type: mirror
          disks:
            - /dev/disk/by-id/ata-WDC_WD40...
            - /dev/disk/by-id/ata-WDC_WD40...

datasets:
  - name: tank/media
    properties:
      compression: lz4
      quota: 4T
      atime: off

shares:
  - name: media
    path: /mnt/tank/media
    users: [alice, bob]

stacks:
  - name: jellyfin
    source: ./stacks/jellyfin/
  • sync_alt
    Bi-directional reconciliation — apply from Git to the live system, or capture live state back into Git. Either direction, at any time.
  • security
    Destruction is blocked — pool destroy is always blocked. Dataset destroy is blocked when zfs get used is non-zero. A git push cannot wipe data.
  • bolt
    Drift detection — background reconciler runs every 5 minutes and broadcasts drift events to connected clients in real time over WebSocket.
  • settings
    Manages structure, not data — dataset properties, share configs, stack definitions, users. ZFS send streams and file contents stay on ZFS's own terms.
  • check
    Stable device paths enforced/dev/disk/by-id/ paths required. Short /dev/sdX paths are rejected at state.yaml parse time, before execution.
High Availability
Two Nodes. No Single Point of Failure.
Shared-SAS or replicated-ZFS topologies. Patroni manages PostgreSQL failover. SCSI-3 Persistent Reservations fence the storage at the hardware level before any software acts.
Shared-SAS topology (recommended, no witness required):           VIP (Keepalived)           |           +------------------+           v                 v Node A - PRIMARY   Node B - STANDBY Patroni primary    Patroni replica SCSI-3 PR owner    SCSI-3 PR standby ZFS pools mounted  ZFS pools held etcd A + witness   etcd B           |                 |           +--------+--------+                   v         [Disk Shelf]         SCSI-3 PR enforced         at controller level

SCSI-3 PR Fencing

Reservations survive reboots (APTPL=1). The SAS controller rejects writes from the non-reservation-holder at the hardware level. No BMC required.

Patroni + etcd

PostgreSQL streaming replication. Automatic failover in 10-30s. HAProxy routes to the current primary. The daemon reconnects within seconds.

Keepalived VIP

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.

Rolling OTA

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.

Comparison
How Does It Stack Up?
DPlaneOS is a management layer that installs as a NixOS appliance. It runs on hardware you own, on top of an OS you control.
Feature DPlaneOS TrueNAS SCALE OpenMediaVault
Install typeNixOS ISO applianceDebian-based own OSDebian plugin layer
Web UI frameworkReact 19 + TypeScriptAngularPHP / 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
Security
Hardened by Architecture.
Every API input validated before reaching the exec layer. Every command goes through the allowlist. Every state change logged in a tamper-evident HMAC chain.
check

Exec Allowlist

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.

check

libzfs CGO in Production

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.

check

HMAC Audit Chain

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.

check

RBAC Authorization

4 roles, 31 permissions enforced at the handler level via permRoute() middleware. System roles are immutable. Role assignments support expiry dates.

check

Fail-Closed Sessions

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.

check

TOTP Two-Factor Auth

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.

check

Daemon Hardening

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.

check

Rate Limiting

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.

check

NixOS Impermanence

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.

Changelog
Recent Changes.
Active development. The v11.6.x series shipped hardening, reliability fixes, and major infrastructure improvements across five releases in May 2026.
v11.6.4 — 2026-05-24
OTA Health Check Hardening
ZFS command failure in the post-OTA health check now triggers auto-revert instead of silently passing as "no degraded pools." Database unreachability in the Samba gate check now increments the failure counter instead of being silently skipped.
RELIABILITY
v11.6.3 — 2026-05-24
Security & Error Propagation
Critical: RBAC hierarchy bypass on DB read failure patched. Last-admin deactivation guard bypass patched. First-boot setup gate re-run vulnerability patched. Three silent audit log failures now surfaced with warnings.
SECURITY
v11.6.2 — 2026-05-24
Error Handling & Reliability
Every db.Exec and rows.Scan call that previously discarded its error return is now checked across all handler files. Silent DB write failures that returned success:true to the client regardless of outcome are fixed throughout.
RELIABILITY
v11.6.0 — 2026-05-22
Infrastructure
Production daemon now uses libzfs CGO (no subprocess for ZFS ops). Fixed OTA auto-revert firing on wrong health endpoint. HA ZFS import guard infinite loop patched. etcd cluster state and network config now persist across OTA slot swaps.
INFRASTRUCTURE
Get Started
Boot the ISO. Running in Minutes.
v11.6.4
May 2026 · NixOS Appliance ISO · Offline installer
amd64 arm64 Raspberry Pi 5
Download →
# Verify the checksum first
sha256sum -c dplaneos-v11.6.4-installer-amd64.iso.sha256

# Write to USB (replace /dev/sdX with your device)
sudo dd if=dplaneos-v11.6.4-installer-amd64.iso \
    of=/dev/sdX bs=4M status=progress conv=fsync

# Boot the installer, follow the prompts (5-10 min)
# Then open your browser to complete setup:
http://<server-ip>/