A lightweight NAS management UI written in Go — built for Linux and FreeBSD, designed to stay as close to a vanilla system as possible.

No container runtime. No database. No Node.js. Just a single compiled binary, some Ansible playbooks, and a handful of static files. Where dumpstore manages a service, it owns the config completely — rendered from a template, never patched.

Go 1.22+ Linux FreeBSD ZFS / OpenZFS no external Go deps stdlib only

features

pool overview ONLINE

Health badges, usage bars, fragmentation, dedup ratio, and the full vdev tree per pool.

scrub management scrub

Trigger and cancel pool scrubs. Last scrub time, status, and progress shown per pool.

I/O statistics live

Read/write IOPS and bandwidth per pool — pushed via Server-Sent Events every 10 s. Falls back to REST polling.

dataset browser filesystem

Collapsible depth-indented tree. Compression, quota, mountpoint. Inline editing of any ZFS property.

snapshots snapshot

List, create (with recursive option), and delete snapshots — all with styled confirm dialogs. Page darkens and a live spinner appears immediately when any write operation runs.

dataset rename zfs rename

Rename a dataset or volume in place. Same-parent constraint enforced — only the leaf name changes, the pool and parent path stay fixed. Backed by an Ansible playbook with full op-log feedback.

snapshot clone zfs clone

Create a new writable dataset from any existing snapshot. Pick the source snapshot and enter a name for the clone — the clone appears immediately in the dataset browser as an independent filesystem.

user management users

Create, edit (shell, password, groups, home directory, SSH authorized keys, Samba password sync), and delete local users. System accounts (uid < 1000) hidden by default — toggle to reveal.

group management groups

Create, edit (name, GID, members), and delete local groups. System groups hidden by default with the same toggle.

ACL management POSIX / NFSv4

View, add, and remove POSIX and NFSv4 ACL entries per dataset. One-click acltype enable. Recursive apply.

NFS sharing sharenfs

Enable, configure, and disable NFS sharing per dataset via the ZFS sharenfs property. Cross-platform (Linux & FreeBSD).

SMB sharing usershares

Samba usershares per dataset. Manage Samba users. dumpstore takes full ownership of smb.conf — rendered from a template on every write. All sub-features gated behind one-time initialisation; directories created automatically on apply.

SMB home shares [homes]

Enable the Samba [homes] section so each authenticated user gets a personal share mapped to a subdirectory. Pick a ZFS dataset as base path or specify a custom path. Base directory created automatically on apply.

Time Machine shares vfs_fruit

Create Samba shares configured as macOS Time Machine backup targets using vfs_fruit. Multiple named shares each backed by a different ZFS dataset. Configurable max size quota and valid users; target directory created automatically on apply.

auto-snapshot scheduling com.sun:auto-snapshot

Manage com.sun:auto-snapshot* ZFS properties per dataset. Integrates with zfs-auto-snapshot (Linux) and zfstools (FreeBSD) for automatic snapshot rotation with configurable keep counts. Button state updates live via SSE (autosnapshot.query topic).

iSCSI target management targetcli / ctld

Expose ZFS volumes as iSCSI targets. Per-zvol dialog with auto-generated IQN (editable), portal IP/port, auth mode (None or CHAP with credentials), and initiator ACL list. Backed by targetcli/LIO on Linux and ctld on FreeBSD.

Service management systemd / rc.d

Start, stop, restart, enable, and disable Samba, NFS, and iSCSI from the Services tab. Live status badges update via SSE every 10 s. Mutations go through Ansible playbooks with full op-log display. Stopping NFS surfaces a client-disconnect warning.

TLS / HTTPS --tls

Enable HTTPS with --tls. Generate a self-signed ECDSA-P256 certificate via the UI (openssl, via Ansible), load an existing cert from disk (Let's Encrypt, Certbot, acme.sh), or issue and renew automatically via lego (ACME / Let's Encrypt). HTTP redirects to HTTPS automatically. Cert status card shows CN, SANs, and expiry countdown.

S.M.A.R.T. health smartctl

Temperature, power-on hours, reallocated sectors, pending sectors, and uncorrectable errors per drive.

system info sysinfo

Hostname, OS, kernel, CPU, uptime, load averages, and process stats. Software inventory tab shows versions of all runtime tools (Go, ZFS, Ansible, smartctl, etc.).

network interfaces network

Read-only overview of all network interfaces: state (up/down), MAC, MTU, IPv4/IPv6 addresses, link speed, and RX/TX byte counters. Virtual and loopback interfaces are shown but muted.

mountpoint ownership chown

View and set the owner and group of a dataset's mountpoint directly from the dataset browser. Backed by an Ansible playbook with full op-log feedback.

Prometheus metrics /metrics

Go runtime, HTTP request counters & latency histograms, and Ansible playbook run metrics out of the box.

Request ID correlation logging

Every request gets a unique req_id that appears on all log lines for that request — errors, warnings, and the access log line — so you can reconstruct the full lifecycle of any concurrent request. Reads X-Request-ID from upstream proxies (nginx, Traefik) and echoes it back on the response.

Audit logging logging

Every mutating operation (dataset, snapshot, user, group, ACL, SMB, iSCSI, scrub) emits a structured slog audit line with remote_ip, action (e.g. dataset.create), target resource, and outcome (ok/err). The req_id is included automatically, linking the audit entry to the full request log.

Authentication security

Session-based login with a argon2id-hashed password stored in /etc/dumpstore/dumpstore.conf (Linux) / /usr/local/etc/dumpstore/dumpstore.conf (FreeBSD). Set up during install via --set-password. Per-IP rate limiting (10 attempts/60 s). Reverse proxy delegation via X-Remote-User from trusted CIDRs. No password configured? The service binds to loopback only until one is set. Change password or username any time from the Users & Groups tab.

planned

ZFS native encryption planned

Load/unload keys, show encryption status per dataset, support keyformat and keylocation.

ZFS send/receive planned

Pool replication and off-site backup via ZFS send/receive streams.

why this exists

I run a Kobol Helios64 as my home NAS — a five-bay ARM board that deserves better than the software ecosystem currently offers it. The existing storage UIs I tried were either too heavy, too opinionated about the underlying distribution, or simply unmaintained. None of them gave me a clean, no-nonsense window into my ZFS pools without pulling in a container runtime, a database, or a Node.js server alongside them.

What I wanted was simple: observe and manage my storage from a browser, on a machine that stays as close to a vanilla Linux or FreeBSD installation as possible. No agents, no daemons-within-daemons, no frameworks that outlive their welcome. Just a single compiled binary, some Ansible playbooks, and a handful of static files with a lightweight reactive store for efficient UI updates.

Where dumpstore does manage a service — Samba, NFS, iSCSI — it takes full, explicit ownership of that service's config file. The config is rendered from a template on every write; no block-patching, no partial edits. If you need to run those services alongside another management tool, dumpstore is not the right fit for that service.

If you run a Helios64, an old server, or any ZFS box where you care about what is actually installed on it, this might be the tool for you.

screenshots

Sysinfo, storage pools, and disk health
system info, pool overview & disk health
Dataset browser with ACL, NFS, and SMB actions
dataset browser
Snapshot management
snapshot management
Users, groups, and SMB users
users, groups & SMB users
Edit dataset properties
edit dataset properties
Create user dialog
create user
Delete snapshot confirmation dialog
delete snapshot confirmation
Users & Groups with system users revealed
system users & groups

install

1

clone and install

git clone https://github.com/langerma/dumpstore.git
cd dumpstore
sudo ./install.sh

Thin wrapper around make install. Auto-installs Go and Ansible if absent, compiles the binary, copies everything to /usr/local/lib/dumpstore/, prompts for an admin password, then registers and starts the service — systemd on Linux, rc.d on FreeBSD.

2

open the UI

http://localhost:8080

Sign in with the password you set during install. Change it any time from the Authentication section in the Users & Groups tab.

3

uninstall

sudo ./install.sh --uninstall

run without installing

go build -o dumpstore .
sudo ./dumpstore -addr :8080 -dir .

-dir must point to the directory containing playbooks/ and static/. Defaults to the directory of the executable.

requirements

dependency Linux FreeBSD
Build Go 1.22+ Go 1.22+
ZFS zfsutils-linux built-in
Ansible ansible (Python 3) py311-ansible
S.M.A.R.T.optional smartmontools smartmontools pkg
POSIX ACLsoptional acl py311-pylibacl
NFSv4 ACLsoptional nfs4-acl-tools nfs4-acl-tools port
NFS sharingoptional nfs-kernel-server / nfs-utils built-in base system
SMB sharingoptional samba samba pkg
iSCSI targetsoptional targetcli-fb built-in ctld

security

dumpstore has built-in session-based authentication. A argon2id-hashed password is set during install and stored in /etc/dumpstore/dumpstore.conf (Linux) / /usr/local/etc/dumpstore/dumpstore.conf (FreeBSD). If no password is configured the service binds to 127.0.0.1 only. dumpstore runs as root (required for ZFS). See SECURITY.md for notes on TLS and the recommended deployment topology.