Root Filesystem

Introduction

The root filesystem module defines a shared Disko layout for Btrfs and ZFS hosts. It can create a new encrypted disk layout or mount explicitly supplied existing partitions, and optionally resets the root filesystem at boot while preserving declared state.

Requirements

New layouts require a stable disk identifier and are applied through Disko. Existing layouts require explicit EFI, root, and optional swap partition paths. Encrypted installations also require the host’s early-boot unlock strategy to be available before deployment.

Minimal Configuration

rootFs = {
  enable = true;
  backend = "zfs";
  diskId = "/dev/disk/by-id/nvme-example";
  homeUsers = ["alice"];
};

Set existingPartitions instead of diskId when adopting partitions that must not be repartitioned. Keep service state in persistDirectories, persistFiles, or named volumes whenever impermanence is enabled.

Invariants

  • diskId and existingPartitions describe mutually exclusive provisioning modes.
  • Enabling impermanence requires every durable service path to be declared explicitly.
  • Changing the backend or disk layout is a storage migration, not a routine configuration switch.

Recovery

Boot a NixOS installer, unlock encrypted devices manually, and import or mount the configured backend before attempting repair. Verify persistent paths and datasets before switching the configuration; never run the installation workflow against a disk containing data that has not been backed up.

Options

rootFs.enable

Whether to enable managed root filesystem layout.

Type: boolean

Default:

false

Example:

true

Declared by:

rootFs.backend

Filesystem backend used for the root layout.

Type: one of “btrfs”, “zfs”

Default:

"zfs"

Declared by:

rootFs.diskId

Disk id path for the main system disk.

Type: null or string

Default:

null

Declared by:

rootFs.encrypted

Encrypt the root filesystem partition with LUKS.

Type: boolean

Default:

true

Declared by:

rootFs.existingPartitions

Existing partitions to use without modifying their parent partition table.

Type: null or (submodule)

Default:

null

Example:

{
  efiDevice = "/dev/disk/by-partlabel/EFI";
  rootDevice = "/dev/disk/by-partlabel/nixos";
  swapDevice = "/dev/disk/by-partlabel/swap";
}

Declared by:

rootFs.existingPartitions.efiDevice

Existing EFI system partition mounted at /boot.

Type: string

Declared by:

rootFs.existingPartitions.rootDevice

Existing partition used for the root filesystem.

Type: string

Declared by:

rootFs.existingPartitions.swapDevice

Optional existing partition used for randomly encrypted swap.

Type: null or string

Default:

null

Declared by:

rootFs.homeUsers

Users that receive dedicated home filesystems.

Type: list of string

Default:

[ ]

Declared by:

rootFs.impermanent

Reset the root filesystem at boot and persist declared state.

Type: boolean

Default:

true

Declared by:

rootFs.persistDirectories

Directories to persist when impermanence is enabled.

Type: list of string

Default:

[ ]

Declared by:

rootFs.persistFiles

Files to persist when impermanence is enabled.

Type: list of string

Default:

[ ]

Declared by:

rootFs.persistPath

Mount path for persisted state.

Type: string matching the pattern ^/.*

Default:

"/persist"

Declared by:

rootFs.swapSize

Swap partition size for the Disko layout.

Type: string

Default:

"32G"

Declared by:

rootFs.volumes

Additional persistent root-pool volumes.

Type: attribute set of (submodule)

Default:

{ }

Example:

{
  database = {
    mountpoint = "/var/lib/example";
    quota = "20G";
  };
}

Declared by:

rootFs.volumes.<name>.autoSnapshot

Whether scheduled local snapshots include this volume.

Type: boolean

Default:

true

Declared by:

rootFs.volumes.<name>.mountpoint

Absolute mountpoint for the persistent volume.

Type: string matching the pattern ^/.*

Declared by:

rootFs.volumes.<name>.quota

Optional backend-specific volume size limit.

Type: null or string

Default:

null

Declared by:

rootFs.zfs.arcMaxPercent

Maximum ZFS ARC size as a percentage of physical memory.

Type: integer between 1 and 100 (both inclusive)

Default:

50

Declared by: