democratic-csi: ZFS-backed storage drivers for Kubernetes
csi storage for container orchestration systems
At a glance
- What is it?
- democratic-csi is a set of Container Storage Interface drivers that provision storage from ZFS systems such as FreeNAS, TrueNAS and ZoL over NFS, iSCSI, SMB and NVMe-oF, and it doubles as a framework for writing new CSI drivers. The drivers are shipped as container images with a Helm chart, and the newest release is v1.1.0 from 2026-10-01.
- Who is it for?
- democratic-csi fits a homelab or on-premises operator who already owns a ZFS box, FreeNAS or TrueNAS or ZoL, and wants persistent volumes in Kubernetes with snapshots, clones and resizing rather than a cloud block store. It does not fit a cluster whose storage is EBS, Ceph or a managed filesystem, or a team that needs the experimental TrueNAS SCALE API drivers in production.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 20 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Twenty drivers over the same ZFS primitives, plus a framework to add more
democratic-csi implements the Container Storage Interface specification, which is how Kubernetes asks a storage system for volumes. The description calls it storage for container orchestration systems, and the current focus is providing storage via iSCSI and NFS from ZFS-based systems, predominantly FreeNAS and TrueNAS, and ZoL on Ubuntu.
The driver list is long, and reading it explains the design. The `freenas-*` family manages ZFS datasets shared over NFS, ZFS zvols shared over iSCSI, datasets over SMB, and zvols over NVMe-oF. The `freenas-api-*` family does the same four things but through the TrueNAS API rather than by driving the system over SSH, and each of those four is marked experimental and for SCALE only. The `zfs-generic-*` family works with any ZoL installation, so Ubuntu, while the `zfs-local-*` drivers provision node-local datasets and zvols.
Then there are the deliberately simple ones, and the README is honest about them. The `lustre-client`, `nfs-client` and `smb-client` drivers are described as crudely provisioning storage using a shared share or directory for all volumes, and `local-hostpath` does the same with node-local directories. `objectivefs` manages objectivefs volumes, `node-manual` connects to manually created volumes with sample PersistentVolumes in the `examples` directory, and two drivers provision ephemeral read-write node-local storage using OCI images or VHD images as a base.
The second half of the project is a framework for developing CSI drivers, and the project asks people to open an issue if they want to contribute one. That is the part that makes the repository interesting beyond ZFS: the driver implementations are the worked examples, and the framework is what other storage backends would be built on.
The gRPC side is Node.js, with Kubernetes client, SSH and templating
The implementation language is JavaScript, and the dependency list in `package.json` shows the shape of the thing.
The gRPC stack is `@grpc/grpc-js` with `@grpc/proto-loader`, which is what a CSI driver is: a gRPC server implementing the CSI service. On the cluster side, `@kubernetes/client-node` at ^0.18.0 handles talking to the API server. The CSI protocol definitions live in the repository as `csi_proto/` and `csi_proxy_proto/` directories rather than being pulled from a remote copy.
Two dependencies explain the driver implementations. `ssh2` is how the `freenas-*` drivers reach the storage system and run ZFS commands, and `handlebars` is the templating engine used to generate the storage class and driver configuration from a `values.yaml`. `axios` covers the HTTP calls, including the TrueNAS API used by the `freenas-api-*` drivers. `js-yaml`, `fs-extra`, `lru-cache` and `uuid` round out the utility layer, `winston` and `bunyan` are the two logging libraries, and `yargs` handles the command line.
The manifest also has a detail worth flagging. The `test` script reads `"echo \"Error: no test specified\" && exit 1"`, which is the placeholder npm generates for a project with no test script. There is no unit test suite in the root manifest. What exists instead is a `ci/` directory and a `hack/` directory, so verification happens in continuous integration and in developer scripts rather than in a test command you can run locally.
The `main` entry point is `bin/democratic-csi` and the `start` script runs it, so the driver is a Node process that speaks gRPC on one side and Kubernetes and ZFS on the other.
Node prep is the part that differs most between operating systems
The installation has three parts: node preparation on the Kubernetes cluster nodes, server preparation on the storage server, and deploying the driver into the cluster, with a Helm chart and a sample `values.yaml` provided.
Node prep means installing the client packages for whichever protocols your storage class will use. For SMB, the CIFS utilities:
# RHEL / CentOS
sudo yum install -y cifs-utils
# Ubuntu / Debian
sudo apt-get install -y cifs-utilsFor NFS the package names differ between the two families, `nfs-utils` on RHEL and CentOS and `nfs-common` on Ubuntu and Debian.
The iSCSI setup is the longest, because it also covers multipathing. On RHEL and CentOS:
# Install the following system packages
sudo yum install -y lsscsi iscsi-initiator-utils sg3_utils device-mapper-multipath
# Enable multipathing
sudo mpathconf --enable --with_multipathd y
# Ensure that iscsid and multipathd are running
sudo systemctl enable iscsid multipathd
sudo systemctl start iscsid multipathd
# Start and enable iscsi
sudo systemctl enable iscsi
sudo systemctl start iscsiOn Ubuntu and Debian the equivalent installs `open-iscsi lsscsi sg3-utils multipath-tools scsitools` and writes a `multipath.conf` with `user_friendly_names yes` and `find_multipaths yes` before enabling the services.
The project notes that multipath is supported for the iSCSI-based drivers, and that you set it up as you like and set multiple portals in the config as appropriate. There is also a specific pointer for Rancher and RKE users to a known issue, and a Talos section, because Talos has no iSCSI support by default and needs an extension image added as a machine configuration patch, after which the nodes have to be upgraded even if there is no update, because the extension does not activate until then.
Each driver has its own example YAML, and that is where the real config lives
The `examples/` directory is the documentation for configuration, and it is organised per driver. There are files for the FreeNAS drivers, one each for `freenas-nfs`, `freenas-iscsi`, `freenas-smb` and `freenas-nvmeof`, and separate ones for the API variants `freenas-api-nfs`, `freenas-api-iscsi`, `freenas-api-smb` and `freenas-api-nvmeof`. There are ones for `local-hostpath`, `lustre-client`, `nfs-client`, `smb-client` and `objectivefs`.
There are also shared files that apply across drivers, `node-common.yaml` and `controller-common.yaml`, and a `private.yaml` that is presumably about a private registry, plus the ephemeral inline drivers with pod and storage class files for the containerd OCI and VHD variants, including a Windows pod example.
The `node-manual` family has the most files, one per protocol, and they are PersistentVolume examples rather than storage classes, because that driver attaches to volumes someone created by hand. A node-manual file exists for iscsi, nfs, nvmeof, objectivefs and smb, plus a generic one.
This structure is worth pausing on. A CSI driver is only half the configuration, and the other half is the storage class, which declares which driver handles a claim, which protocol, which parameters the backend needs and whether the volume is bound immediately or late. With roughly twenty drivers, each with its own parameters, the storage classes are where a deployment actually goes wrong, and the per-driver example files are the reference you will be reading.
The `values.yaml` for the Helm chart is the other half, and it is where the driver image, the backend connection details and the storage class templates live, with the handlebars templating letting one chart produce the different drivers.
The image is a Node build on Debian slim, and the containerd binaries are patched
The `Dockerfile` builds the driver as a Node application, and the details are specific enough to be worth reading.
The base is `debian:12-slim`, with a commented-out `debian:10-slim` alternative that is switched on with the `--platform=$BUILDPLATFORM` flag for cross-platform builds. The Node version is pinned as an environment variable, `NODE_VERSION=v20.19.0`, and installed by a script fetched into `/usr/local/sbin` rather than from the distribution's package manager, so the runtime version is under the project's control.
There is a commented-out golang builder stage, and it is the interesting part. It clones containerd, checks out a specific tag, applies a patch file from `docker/ctr-mount-labels.diff` with `git apply`, and builds `cmd/ctr` with `CGO_ENABLED=0`. The patch adds mount labels to the containerd client. That is the mechanism behind the `containerd-oci-ephemeral-inline` driver, which provisions ephemeral node-local storage using OCI images as a base, and it explains the release names.
Every recent release tag carries the suffix `patched-ctr-binaries`. v1.0.0 from 2025-10-24, v1.0.1 from 2026-09-30 and v1.1.0 from 2026-10-01 are all named that way, which tells you the patched containerd client is a shipped artefact of the release rather than something built on demand by each user.
The runtime image also drops privileges, creating a `csi` user and running the application as that user rather than as root, and it sets up a working directory under `/home/csi/app`. There is a `Dockerfile.Windows` as well, matching the Windows pod example in the examples directory, so the ephemeral inline drivers are not Linux-only. The top-level `Vagrantfile` and `.devcontainer/` suggest a local development environment for people writing new drivers against the framework.
The SCALE API drivers are the experimental edge
Five of the drivers are marked experimental, and they are the ones to be careful with.
The four `freenas-api-*` drivers, for NFS, iSCSI, SMB and NVMe-oF, are each described as experimental and for SCALE only. They differ from the plain `freenas-*` drivers in how they reach the storage system: the API drivers talk to the TrueNAS API over HTTP, while the others drive the system over SSH with `ssh2`. Using an API is the more direct route and avoids shell quoting and remote command execution, so the direction is sensible, but the status is explicitly experimental and limited to one TrueNAS distribution.
The other experimental entry is `synology-iscsi`, which manages volumes shared over iSCSI, so the project has support for one non-ZFS storage system even though ZFS is the focus.
The `node-manual` driver sits at the other end of the maturity scale. It lets you connect to manually created SMB, NFS, Lustre, OneClient, NVMe-oF and iSCSI volumes, and it comes with sample PersistentVolumes. That is a useful escape hatch for a cluster where you want to control volume creation outside the driver, and the sample files are the fastest way to understand the shape of a manual PV for each protocol.
A note on the naming: `objectivefs` appears both as a driver and as a node-manual protocol, and `OneClient` is listed as a manual protocol in the README. Those are separate from the ZFS story, so read the driver list rather than assuming every entry is ZFS-backed.
Where democratic-csi is the wrong tool
The obvious case is a cluster on cloud storage. The whole driver set assumes a ZFS backend you operate yourself, on a box on your network. If your persistent volumes are EBS, EFS or a managed filesystem, a CSI driver for a home NAS is the wrong tool and the built-in provisioners are the right answer.
The second case is storage that is not ZFS and not reachable over the protocols listed. The driver families cover NFS, iSCSI, SMB, NVMe-oF, Lustre, OneClient and objectivefs, which is broad, but a backend that only speaks a proprietary API is not covered. The `node-manual` driver is a partial escape, since it attaches to a volume someone created by another system, but that volume still has to be reachable over one of the supported protocols.
The third case is a team that needs the SCALE API drivers to be reliable. They are marked experimental and limited to SCALE, and the `freenas-*` SSH-based drivers are the supported path. Running the experimental set in production means owning the driver behaviour yourself, and the alternative within the same project is the SSH driver that the maintainers treat as the primary one.
There is also the packaging reality. The `test` script in the manifest is the npm placeholder that exits with an error, so there is no local test command to run before a change. Verification lives in the CI configuration and in the per-driver example manifests, which means the practical safety net is deploying the driver and exercising a storage class in a cluster, not a unit test run on a laptop.
Editorial conclusion
democratic-csi fits a homelab or on-premises operator who already owns a ZFS box, FreeNAS or TrueNAS or ZoL, and wants persistent volumes in Kubernetes with snapshots, clones and resizing rather than a cloud block store. It does not fit a cluster whose storage is EBS, Ceph or a managed filesystem, or a team that needs the experimental TrueNAS SCALE API drivers in production. Before deploying, read the driver-specific example YAML under `examples/`, because each of the roughly twenty drivers has its own storage class parameters, and note that the `freenas-api-*` family is marked experimental and SCALE only.
Frequently asked questions
Which storage backends does democratic-csi support?
The drivers provision from ZFS-based systems, predominantly FreeNAS and TrueNAS and ZoL on Ubuntu, over NFS, iSCSI, SMB and NVMe-oF. There are also drivers for Lustre, objectivefs, node-local datasets and zvols, node-local directories, and manual attachment of existing volumes.
How do I install democratic-csi in a Kubernetes cluster?
The process has three parts: prepare the cluster nodes with the client packages for the protocol you use, prepare the storage server, then deploy the driver with the provided Helm chart and a `values.yaml`. The node prep covers cifs-utils for SMB, nfs-utils or nfs-common for NFS, and the iSCSI and multipath packages for the iSCSI drivers.
What does the freenas-api driver add over freenas-nfs?
The `freenas-api-*` drivers manage ZFS datasets and zvols through the TrueNAS API instead of over SSH, and they are marked experimental and for SCALE only. The plain `freenas-*` drivers, which drive the system over SSH, are the primary path.
Is democratic-csi still being updated?
Yes, the repository is not archived and the last push was on 2026-10-03. The recent releases are v1.1.0 on 2026-10-01, v1.0.1 on 2026-09-30 and v1.0.0 on 2025-10-24, each tagged `patched-ctr-binaries`.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/democratic-csi-democratic-csi)Was this useful?