Overview

WolfDisk is a distributed file system that provides easy-to-use shared and replicated storage across Linux machines. Mount a shared directory on any number of servers and have your data automatically synchronised. Built on the same proven consensus mechanisms as WolfScale.

🎬 Watch the overview video: WolfDisk on YouTube

Key Features

  • FUSE-based — Mount as a regular Linux directory using FUSE3
  • Content-addressed deduplication — Automatic deduplication via SHA256 hashing
  • Chunk-based storage — Large files split into 4 MB chunks for efficient transfer and sync
  • Leader / Follower / Client modes — Flexible node roles for any deployment
  • Auto-discovery — UDP multicast for automatic peer discovery on LAN
  • Automatic leader election & failover — Deterministic election with 2-second failover
  • Delta sync — Incremental catchup — only missed changes are transferred
  • S3-compatible REST API — Optional S3 gateway for any S3 client
  • Bucket → folder mapping — Point any S3 bucket name at any folder inside WolfDisk via [s3.buckets]
  • LZ4 compression — Compressed network replication
  • Symlink support — Full POSIX symlink support
  • IBM Power ready — Pure Rust dependencies, builds natively on ppc64le

Node Roles

Every WolfDisk node operates in one of four roles:

Role Storage Replication Use Case
Leader ✅ Yes Broadcasts to followers Primary write node
Follower ✅ Yes Receives from leader Read replicas, failover candidates
Client ❌ No None (mount-only) Access the drive remotely without local storage
Auto ✅ Yes Dynamic election Default — lowest node ID automatically becomes leader

💡 Client Mode is perfect for workstations or containers that just need to access the shared filesystem without storing data locally.

Quick Install

The interactive installer handles dependencies, compilation, configuration, and systemd service setup:

bash
curl -sSL https://raw.githubusercontent.com/wolfsoftwaresystemsltd/WolfScale/main/wolfdisk/setup.sh | bash

The installer will prompt you for:

  • Node ID — Unique identifier (defaults to hostname)
  • Role — auto, leader, follower, or client
  • Bind IP address — IP to listen on (auto-detected)
  • Discovery method — Auto-discovery (UDP multicast), manual peers, or standalone
  • Mount path — Where to mount the filesystem (default: /mnt/wolfdisk)

⚠️ Compilation note: The installer compiles WolfDisk from source using Rust. This is CPU-intensive and may take several minutes. Please wait for it to complete.

Manual Installation

Prerequisites

  • Linux with FUSE3 support
  • Rust toolchain (rustup)

⚠️ Running in an LXC Container?

WolfDisk requires the following features to be enabled in your container settings. Without these, WolfDisk will not start:

  • TUN/TAP Device — Required for WolfDisk networking (/dev/net/tun)
  • FUSE — Required for the FUSE filesystem mount (/dev/fuse)

WolfStack: Go to the container → Settings → enable TUN/TAP Device and FUSE → save → reboot the container.

Proxmox: Go to the container → Options → Features → enable fuse and tun → reboot the container.

If installing via the WolfStack App Store, these settings are applied automatically.

Install Dependencies

bash
# Ubuntu / Debian
sudo apt install libfuse3-dev fuse3

# Fedora / RHEL
sudo dnf install fuse3-devel fuse3

Build & Install

bash
git clone https://github.com/wolfsoftwaresystemsltd/WolfScale.git
cd WolfScale/wolfdisk
cargo build --release
sudo cp target/release/wolfdisk /usr/local/bin/
sudo cp target/release/wolfdiskctl /usr/local/bin/

Docker Install (Unraid / Synology / TrueNAS / any Docker host)

For NAS platforms where compiling from source isn’t practical, WolfDisk ships as a prebuilt multi-arch Docker image alongside WolfNet. Pair them to join a NAS to your WolfStack cluster overlay:

bash
docker run -d --name wolfdisk \
  --restart unless-stopped \
  --privileged --network host \
  --device /dev/fuse:/dev/fuse \
  -v wolfdisk-config:/etc/wolfdisk \
  -v wolfdisk-data:/var/lib/wolfdisk \
  -v /mnt/wolfdisk:/mnt/wolfdisk:rshared \
  -e WOLFDISK_ROLE=client \
  -e WOLFDISK_PEERS=<leader_ip:8550> \
  ghcr.io/wolfsoftwaresystemsltd/wolfdisk:latest

Or use the satellite compose file from the WolfStack repo to bring up WolfNet and WolfDisk together in one go:

bash
WOLFNET_JOIN_TOKEN=<token> WOLFDISK_LEADER=<leader_ip:8550> \
  docker compose -f docker-compose.satellite.yml up -d

Multi-arch: the image works on linux/amd64 and linux/arm64. Get the join token from the WolfStack UI or by running wolfnet invite on any cluster node.

Usage

1. Initialize Data Directory

bash
wolfdisk init -d /var/lib/wolfdisk

2. Mount the Filesystem

bash
# Foreground (for testing)
sudo wolfdisk mount -m /mnt/wolfdisk

# As a systemd service (recommended)
sudo systemctl start wolfdisk

3. Check Status

bash
wolfdiskctl status

4. Use It Like Any Directory

bash
# Write files
echo "Hello, WolfDisk!" > /mnt/wolfdisk/hello.txt
cp /var/log/syslog /mnt/wolfdisk/

# Read files — automatically available on all nodes
cat /mnt/wolfdisk/hello.txt
ls -la /mnt/wolfdisk/

Configuration

WolfDisk is configured via /etc/wolfdisk/config.toml. The installer creates this file for you, or you can edit it manually:

toml
[node]
id = "node1"                    # Unique node identifier
role = "auto"                   # auto, leader, follower, or client
bind = "0.0.0.0:8550"           # IP and port for cluster communication
data_dir = "/var/lib/wolfdisk"  # Where chunks and index are stored

[cluster]
# Auto-discovery (recommended for LAN)
discovery = "udp://239.255.0.1:8551"

# Or manual peers (for cross-subnet / WAN)
# peers = ["192.168.1.10:8550", "192.168.1.11:8550"]

[replication]
mode = "shared"       # "shared" or "replicated"
factor = 3            # Number of copies (replicated mode)
chunk_size = 4194304  # 4 MB chunks

[mount]
path = "/mnt/wolfdisk"
allow_other = true    # Allow other users to access the mount

# Optional: S3-compatible API
[s3]
enabled = true
bind = "0.0.0.0:9878"
# access_key = "your-access-key"   # optional auth
# secret_key = "your-secret-key"   # optional auth

Configuration Reference

Section Key Default Description
[node] id hostname Unique identifier — used in leader election (lowest ID wins)
role auto auto, leader, follower, or client
bind 0.0.0.0:8550 Listen address for cluster communication
data_dir /var/lib/wolfdisk Directory for chunks, index, and WAL
[cluster] discovery UDP multicast address for auto-discovery
peers [] Manual list of peer addresses
[replication] mode shared shared (single leader) or replicated (N copies)
factor 3 Replication factor for replicated mode
chunk_size 4194304 Chunk size in bytes (4 MB)
[mount] path /mnt/wolfdisk FUSE mount point
allow_other true Allow other system users to access the mount
[s3] enabled false Enable S3-compatible REST API
bind 0.0.0.0:9878 S3 API listen address
access_key Optional S3 access key
secret_key Optional S3 secret key
[s3.buckets] name = "folder" Optional bucket → folder map (e.g. photos = "/data/photos"); paths are from the WolfDisk root. See Mapping Buckets to Folders below

Architecture

WolfDisk is composed of several layers that work together:

Linux Applications
mount /mnt/wolfdisk
FUSE (fuser)
WolfDisk Core
File IndexMetadata mapping
Chunk StoreSHA256 content-addressed
Replication EngineLeader election & sync
S3-Compatible API (optional)
ListBuckets / Get / Put / Delete Objects
Network Layer
Discovery + Peer Manager + Protocol

How It Works

  1. FUSE Layer — Applications read/write to /mnt/wolfdisk like a normal directory. The FUSE driver intercepts all filesystem calls.
  2. Chunk Store — Files are split into 4 MB chunks, each identified by its SHA256 hash. Identical data is automatically deduplicated.
  3. File Index — Maps file paths to their chunk references, permissions, size, and modification times.
  4. Replication Engine — Synchronises chunks and index updates across nodes. Handles leader election and failover.
  5. Network Layer — UDP multicast for peer discovery, TCP for data transfer. LZ4 compression for network efficiency.

Leader Election & Failover

WolfDisk uses deterministic leader election — no voting, no delays. The node with the lowest ID is always the leader.

How Failover Works

node-aLeader
node-bFollower
node-cFollower
node-a goes down — timeout after 2 seconds
node-aOffline
node-bNew Leader
node-cFollower
node-a returns — syncs missed changes, resumes as leader (lowest ID)
  • Heartbeat timeout — Nodes monitor the leader with a 2-second timeout
  • Fast election — No voting or consensus delay; lowest node ID always wins
  • Seamless reads — Followers continue serving reads during failover
  • Explicit override — Set role = "leader" to force a specific node as leader

Sync & Replication

Write Replication

When the leader writes a file:

  1. Local write — Leader stores chunks and updates the file index locally
  2. Broadcast — Leader sends the index update and chunk data to all followers
  3. Apply — Followers update their local index and store the chunks

Delta Sync (Catchup)

When a node starts or recovers from downtime, it performs an incremental sync:

Followerversion 45
Leaderversion 50
1
Follower sends SyncRequest(from_version=45)
2
Leader replies with SyncResponse containing 5 changes
3
Follower applies changes, now at version 50

Only missed changes are transferred — a node that was down briefly doesn't need to re-download everything.

Read Caching

Followers cache chunks locally for fast reads:

  • Cache hit — Chunk exists locally → return immediately
  • Cache miss — Fetch chunk from leader → cache locally → return

Client Mode (Thin Client)

Client mode mounts the filesystem without storing any data locally. All reads and writes are forwarded to the leader over the network.

Aspect Leader / Follower Client
Local Storage ✅ Stores data on disk ❌ No local storage
Reads Served locally Forwarded to leader
Writes Local (leader) or forwarded Forwarded to leader
Use Case Data nodes, replicas Workstations, containers

Client mode is ideal for:

  • Workstations accessing shared files
  • Containers that need cluster storage access
  • Read-heavy applications where network latency is acceptable

S3-Compatible API

WolfDisk can optionally expose an S3-compatible REST API, allowing any S3 client (AWS CLI, rclone, MinIO Client, etc.) to read and write files. Both FUSE and S3 access the same underlying data — files written via FUSE are instantly visible through S3, and vice versa.

Enable S3

Add to /etc/wolfdisk/config.toml:

toml
[s3]
enabled = true
bind = "0.0.0.0:9878"
# Optional authentication:
# access_key = "your-access-key"
# secret_key = "your-secret-key"

How It Maps

WolfDisk S3 Equivalent
Top-level directory Bucket
File in directory Object
Nested directory Object key prefix

Buckets

By default, every top-level directory in WolfDisk is a bucket, and the files inside it are objects (nested folders become object key prefixes). Create a directory called backups and you immediately have a backups bucket — there is no separate “create bucket” step. ListBuckets returns every top-level directory it finds, plus any bucket you map explicitly (below).

Mapping Buckets to Folders

You don’t have to expose your folders at the top level. The optional [s3.buckets] table maps a bucket name to any folder inside WolfDisk, so a client connecting to bucket photos can be served from a nested path such as /data/photos:

toml
[s3]
enabled = true
bind = "0.0.0.0:9878"

# Map bucket names to specific folders inside WolfDisk.
# Paths are interpreted from the WolfDisk root; leading/trailing slashes are ignored.
[s3.buckets]
photos  = "/data/photos"
backups = "/srv/backups"
media   = "tenants/acme/media"
  • Listed buckets serve their mapped folder — a client using bucket photos reads and writes under /data/photos, not a top-level photos directory.
  • Unlisted buckets are unchanged — any bucket not in the table still maps to a top-level directory of the same name (the default behaviour), so existing setups keep working exactly as before.
  • Mapped buckets always appear in ListBuckets — even when the target folder isn’t a top-level directory of the same name, so S3 clients can still discover them.
  • Paths are relative to the WolfDisk root — leading and trailing slashes are ignored, so "/data/photos" and "data/photos/" are equivalent.

💡 Edit from the WolfStack dashboard: open the node’s WolfDisk → Configuration → S3-Compatible Gateway section and use the Bucket → Folder Mappings editor to add, change, or remove mappings without hand-editing the TOML. Removing a row deletes that mapping; restart WolfDisk to apply the change.

This is handy for serving a single sub-tree to an S3 client, giving each tenant or app its own bucket name that points at its own folder, or keeping bucket names stable while you reorganise the underlying directories.

Supported Operations

Operation Method Path
ListBuckets GET /
CreateBucket PUT /bucket
DeleteBucket DELETE /bucket
HeadBucket HEAD /bucket
ListObjectsV2 GET /bucket?prefix=...
GetObject GET /bucket/key
PutObject PUT /bucket/key
DeleteObject DELETE /bucket/key
HeadObject HEAD /bucket/key

Examples

bash
# Using AWS CLI
aws --endpoint-url http://localhost:9878 s3 ls
aws --endpoint-url http://localhost:9878 s3 cp file.txt s3://mybucket/file.txt
aws --endpoint-url http://localhost:9878 s3 ls s3://mybucket/

# Using curl
curl http://localhost:9878/mybucket/myfile.txt
curl -X PUT --data-binary @file.txt http://localhost:9878/mybucket/file.txt

CLI Reference

wolfdisk (Service Daemon)

Command Description
wolfdisk init -d PATH Initialize a new WolfDisk data directory
wolfdisk mount -m PATH Mount the filesystem at the given path
wolfdisk unmount -m PATH Unmount the filesystem
wolfdisk status Show node configuration

Options:

  • --config PATH — Path to config file (default: /etc/wolfdisk/config.toml)

wolfdiskctl (Control Utility)

Command Description
wolfdiskctl status Show live status from the running service (role, state, version, file count, size, peers)
wolfdiskctl list servers List all discovered servers in the cluster with roles and status
wolfdiskctl stats Live cluster statistics dashboard (refreshes every second, Ctrl+C to exit)

Options:

  • -s, --status-file PATH — Path to status file (default: /var/lib/wolfdisk/cluster_status.json)

Systemd Service

The installer creates a systemd service for you automatically. Common commands:

bash
# Start WolfDisk
sudo systemctl start wolfdisk

# Check status
sudo systemctl status wolfdisk

# View logs
sudo journalctl -u wolfdisk -f

# Enable on boot
sudo systemctl enable wolfdisk

# Restart after config change
sudo systemctl restart wolfdisk

Multi-Node Setup

A typical deployment has multiple nodes with different roles. All nodes with role = "auto" will automatically elect a leader.

Server 1 (will become leader — lowest ID)

toml
[node]
id = "node-a"
role = "auto"
bind = "192.168.1.10:8550"
data_dir = "/var/lib/wolfdisk"

[cluster]
discovery = "udp://192.168.1.10:8551"

[mount]
path = "/mnt/shared"

Server 2–N (will become followers — higher IDs)

toml
[node]
id = "node-b"          # Higher ID → follower
role = "auto"
bind = "192.168.1.11:8550"
data_dir = "/var/lib/wolfdisk"

[cluster]
discovery = "udp://192.168.1.11:8551"

[mount]
path = "/mnt/shared"

Workstation (client only — no storage)

toml
[node]
id = "desktop"
role = "client"
bind = "192.168.1.50:8550"

[cluster]
peers = ["192.168.1.10:8550", "192.168.1.11:8550"]

[mount]
path = "/mnt/shared"

WolfStack Dashboard

When WolfStack is installed, WolfDisk gets a dedicated cluster management page in the dashboard. You can manage every aspect of your WolfDisk deployment — across hosts, Docker containers, and LXC containers — from a single pane of glass.

Cluster Overview

The dashboard shows a summary of your entire WolfDisk deployment at a glance:

  • Installed nodes — How many hosts and containers have WolfDisk installed
  • Running / Stopped — Service status across all nodes
  • Active clusters — Number of distinct WolfDisk clusters (e.g. “fast-nvme”, “bulk-hdd”)
  • Mounted filesystems — Total active WolfDisk mounts

Nodes are grouped by cluster name, so you can see at a glance which servers belong to which storage pool.

Node Management

Each node — whether a bare-metal host, Docker container, or LXC container — is shown in a table with:

Column Description
Status Running, stopped, failed, or offline indicator
Node Name Hostname or container name
Member Type Host, Docker, or LXC badge
Version Installed version with upgrade indicator when a newer release is available
Role Leader, Follower, Client, or Auto
Actions Start, stop, restart, configure, upgrade

Click any node to expand its detail panel, which shows the full configuration summary: data directory, mount point, bind address, WolfNet mesh address (if configured), replication mode and factor, peer list, and S3 API status.

Configuration Editor

The built-in configuration dialog provides a structured form for editing /etc/wolfdisk/config.toml on any node — no SSH required. Configuration is split into logical sections:

  • Node — Node ID, role, bind address, data directory
  • Cluster — Cluster name, peer discovery settings, peer list with a checkbox picker for known nodes
  • Replication — Mode (shared / replicated) and replication factor
  • Mount — Mount path, allow_other flag
  • S3 — Enable/disable S3 API, custom bind address

Diagnostics

Before starting a node, you can run the built-in configuration diagnostics tool. It validates:

  • Node ID is set
  • Bind address format and port validity
  • Data directory and mount path are configured
  • Peer address formats are correct
  • The wolfdisk binary is installed
  • No port conflicts with other services
  • Multi-user access permissions (FUSE allow_other)

Diagnostics run remotely against the target node in real time, so you catch misconfigurations before they cause failures.

One-Click Install & Upgrade

Install WolfDisk on new hosts or containers directly from the dashboard:

  1. Configure — Set the cluster name, peers, replication mode, and mount path
  2. Install — WolfStack compiles and installs WolfDisk with a live terminal view
  3. Auto-join — If only one WolfDisk cluster exists, new nodes automatically join it

When a newer version is available on GitHub, an upgrade badge appears next to each node. Click Upgrade to pull the latest source, recompile, and restart the service — your configuration is preserved automatically.

💡 Container support: WolfStack automatically enables TUN and FUSE device access when installing WolfDisk into Docker or LXC containers, so you don’t need to configure these manually.

Troubleshooting

WolfDisk fails to start in an LXC container

If WolfDisk fails immediately or you see errors about /dev/fuse or /dev/net/tun not being available, the container is missing required device access:

  1. Stop the container
  2. Go to the container's Settings page
  3. Enable TUN/TAP Device and FUSE
  4. Save and start the container

On Proxmox: Options → Features → fuse, tun. On WolfStack: Settings → TUN/TAP Device ✅, FUSE ✅.

Mount fails with "Transport endpoint not connected"

The FUSE mount is stale. Unmount and remount:

bash
sudo fusermount -u -z /mnt/wolfdisk
sudo systemctl restart wolfdisk

Permission denied on mount

Ensure user_allow_other is enabled:

bash
echo "user_allow_other" | sudo tee -a /etc/fuse.conf

Peers not discovering each other

  • Check that port 8550 (TCP) and 8551 (UDP) are open in your firewall
  • For cross-subnet setups, use peers = [...] instead of UDP discovery
  • Verify bind is set to an accessible IP, not 127.0.0.1

Status file not found

If wolfdiskctl status reports "Status file not found", the service is not running:

bash
sudo systemctl start wolfdisk
sudo journalctl -u wolfdisk -f    # Check for errors

Client Reset

If a client node (not leader/follower!) has a stuck mount or corrupted cache, use the reset script:

bash
sudo bash /opt/wolfscale-src/wolfdisk/reset_client.sh

⚠️ Warning: The reset script wipes /var/lib/wolfdisk. Only use it on client nodes. Running it on a leader or follower will cause data loss.

Network Ports

Port Protocol Purpose
8550 TCP Cluster communication (data, replication, sync)
8551 UDP Auto-discovery (multicast)
9878 TCP S3-compatible API (when enabled)
Esc