A declarative NAS (Network Attached Storage) configuration using NixOS with MergerFS + SnapRAID. Optimized for media streaming, large files, and low-resource hardware.
- MergerFS: Pool multiple disks of different sizes into a single unified storage
- SnapRAID: Snapshot-based parity protection (recover from disk failures)
- Samba & NFS: File sharing for Windows, macOS, and Linux clients
- Web UI: Cockpit (system admin) + File Browser (file management)
- Declarative: Entire system configuration as code with NixOS Flakes
- Easy Deployment: Install remotely via nixos-anywhere
- Secret Management: Passwords encrypted with agenix
- SSO Ready: Optional Authentik integration for single sign-on
┌─────────────────────────────────────────────────────────────┐
│ MERGERFS POOL │
│ /mnt/storage (union) │
│ │
│ ┌─────────────┬─────────────┬─────────────┐ │
│ │ /mnt/disk1 │ /mnt/disk2 │ /mnt/diskN │ (expandable) │
│ │ (any size) │ (any size) │ (any size) │ │
│ │ ext4 │ ext4 │ ext4 │ │
│ └─────────────┴─────────────┴─────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
┌─────────┴─────────┐
│ SNAPRAID │
│ /mnt/parity │
│ (parity disk) │
└───────────────────┘
| Component | Minimum | Recommended |
|---|---|---|
| CPU | x86_64, 2 cores | 4+ cores |
| RAM | 2 GB | 4+ GB |
| System disk | 32 GB | 100+ GB SSD |
| Data disks | 1+ | 2+ (any size mix) |
| Parity disk | 1 (≥ largest data disk) | Same |
- A machine to deploy from (Linux/macOS with Nix installed)
- Target machine bootable via USB (NixOS ISO or any Linux for nixos-anywhere)
git clone https://github.com/josecriane/nixos-nas.git
cd nixos-nas
# Enter dev shell with required tools
nix develop
# Run interactive setup wizard
./scripts/setup.shThe wizard will ask for:
- Network configuration (IP, gateway, DNS)
- Admin username and SSH key
- Samba password
- Which services to enable
Edit modules/disko.nix to match your hardware:
# Change device paths to match your disks
system.device = "/dev/sda"; # System + parity disk
data1.device = "/dev/sdb"; # Data disk 1
data2.device = "/dev/sdc"; # Data disk 2
# Add more data disks as neededBoot the target machine with NixOS ISO, then from your workstation:
./scripts/install.shOr manually with nixos-anywhere:
nixos-anywhere --flake .#nas root@<NAS_IP>The install script handles SSH setup and Samba password configuration automatically.
After installation, initialize SnapRAID parity (this takes several hours on first run):
ssh admin@<NAS_IP>
sudo snapraid sync| Service | Port | Description |
|---|---|---|
| Samba (SMB) | 445 | Windows/Mac/Linux file sharing |
| NFS | 2049 | Linux file sharing (better performance) |
| Cockpit | 9090 | Web-based system administration |
| File Browser | 8080 | Web-based file manager |
| SSH | 22 | Remote administration |
nixos-nas/
├── flake.nix # Flake definition with inputs
├── configuration.nix # Base system configuration
├── config.example.nix # Example configuration (copy to config.nix)
├── modules/
│ ├── disko.nix # Disk partitioning (customize for your hardware)
│ ├── storage-mergerfs.nix # MergerFS pool configuration
│ ├── snapraid.nix # SnapRAID parity and schedules
│ ├── services.nix # Samba and NFS configuration
│ ├── webui.nix # Cockpit and File Browser
│ ├── networking.nix # Network optimizations
│ ├── hardware.nix # Boot and hardware settings
│ ├── users.nix # User management
│ ├── monitoring.nix # Health checks and alerts
│ ├── reverse-proxy.nix # Optional Nginx reverse proxy
│ └── samba-setup.nix # Samba password from agenix
├── scripts/
│ ├── setup.sh # Interactive configuration wizard
│ ├── install.sh # Installation via nixos-anywhere
│ ├── update.sh # Update NAS configuration
│ ├── nas-health.sh # System health check
│ ├── snapraid-status.sh # SnapRAID detailed status
│ ├── add-disk.sh # Add new disk wizard
│ ├── replace-disk.sh # Replace failed disk wizard
│ ├── benchmark.sh # Performance tests
│ └── setup-authentik.sh # Authentik SSO setup (optional)
├── examples/
│ ├── disko-2-data-disks.nix # Minimal: 2 data disks
│ ├── disko-4-data-disks.nix # Medium: 4 data disks
│ ├── disko-nvme-system.nix # NVMe system + HDD data
│ ├── config-minimal.nix # Minimal configuration
│ └── config-full.nix # Full configuration
└── secrets/
└── secrets.example.nix # Example secrets configuration
| File | What to Change |
|---|---|
config.nix |
Network, username, SSH keys, domain |
modules/disko.nix |
Disk devices (/dev/sdX) for your hardware |
secrets/secrets.nix |
Age public keys for secret encryption |
| File | Purpose |
|---|---|
configuration.nix |
Enable/disable services, firewall rules |
modules/services.nix |
Samba shares, NFS exports |
modules/snapraid.nix |
Sync schedule, scrub frequency |
This project uses agenix for secret management.
-
Copy the example:
cp secrets/secrets.example.nix secrets/secrets.nix
-
Get your NAS's age key (after first boot):
ssh admin@nas "cat /etc/ssh/ssh_host_ed25519_key.pub" | ssh-to-age
-
Add your admin key:
ssh-to-age < ~/.ssh/id_ed25519.pub
-
Update
secrets/secrets.nixwith both keys -
Create encrypted secrets:
echo "your-password" | age -r "age1..." -o secrets/samba-password.age
These run automatically via systemd timers:
| Task | Schedule | Description |
|---|---|---|
| SnapRAID sync | Daily 2 AM | Update parity data |
| SnapRAID scrub | Weekly (Sun 3 AM) | Verify 8% of data |
| SMART monitoring | Continuous | Disk health checks |
Run these when you need to check status or force immediate sync:
nas-status # System overview
sudo snapraid status # SnapRAID status
sudo snapraid diff # Changes since last sync
sudo snapraid sync # Force immediate sync
sudo snapraid scrub -p 10 # Verify 10% of data# Use the wizard
sudo ./scripts/add-disk.sh
# Or manually:
# 1. Add disk to modules/disko.nix
# 2. Add to modules/storage-mergerfs.nix
# 3. Add to modules/snapraid.nix
# 4. nixos-rebuild switch
# 5. snapraid sync# Use the wizard
sudo ./scripts/replace-disk.sh
# Or manually:
# 1. Replace failed disk
# 2. Format with same label: mkfs.ext4 -L diskN /dev/sdX1
# 3. Mount: mount /dev/sdX1 /mnt/diskN
# 4. Recover: snapraid fix -d diskN| Feature | MergerFS + SnapRAID | ZFS | Traditional RAID |
|---|---|---|---|
| RAM usage | < 1 GB | 4-8+ GB | Low |
| Mixed disk sizes | ✅ Yes | ❌ No | ❌ No |
| Easy expansion | ✅ Add anytime | Complex | Rebuild required |
| Individual disk access | ✅ Yes | ❌ No | ❌ No |
| File-level recovery | ✅ Yes | Pool-level | No |
| Real-time protection | ❌ Snapshot | ✅ Yes | ✅ Yes |
| Best for | Media, static files | Databases, VMs | Enterprise |
For a home NAS with limited RAM serving media files, MergerFS + SnapRAID is ideal.
- SnapRAID is not real-time: Changes are only protected after a sync
- Parity disk size: Must be ≥ your largest data disk
- Not a backup: Protects against disk failure, not accidental deletion or ransomware
- Single parity: Default config tolerates 1 disk failure (can add 2-parity)
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Run
nix flake checkto verify - Submit a pull request
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.