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.
features
Health badges, usage bars, fragmentation, dedup ratio, and the full vdev tree per pool.
Trigger and cancel pool scrubs. Last scrub time, status, and progress shown per pool.
Read/write IOPS and bandwidth per pool — pushed via Server-Sent Events every 10 s. Falls back to REST polling.
Collapsible depth-indented tree. Compression, quota, mountpoint. Inline editing of any ZFS property.
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.
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.
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.
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.
Create, edit (name, GID, members), and delete local groups. System groups hidden by default with the same toggle.
View, add, and remove POSIX and NFSv4 ACL entries per dataset. One-click acltype enable. Recursive apply.
Enable, configure, and disable NFS sharing per dataset via the ZFS sharenfs property. Cross-platform (Linux & FreeBSD).
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.
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.
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.
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).
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.
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.
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.
Temperature, power-on hours, reallocated sectors, pending sectors, and uncorrectable errors per drive.
Hostname, OS, kernel, CPU, uptime, load averages, and process stats. Software inventory tab shows versions of all runtime tools (Go, ZFS, Ansible, smartctl, etc.).
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.
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.
Go runtime, HTTP request counters & latency histograms, and Ansible playbook run metrics out of the box.
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.
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.
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
Load/unload keys, show encryption status per dataset, support keyformat and keylocation.
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
install
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.
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.
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.