Sanoid Block

Defined in /modules/blocks/sanoid.nix:

{
  imports = [
    inputs.selfhostblocks.nixosModules.sanoid
  ];
}

Provider Contracts

This block provides the following contracts:

Usage

Sanoid uses templates to know when snapshots should be kept or pruned.

Default Template

Backup a dataset using the default Sanoid template:

{
  shb.zfs.pools.root.datasets.home = {
    path = "/home";
  };

  shb.sanoid.backup."root/home" = {
    request = shb.zfs.pools.root.datasets.home.datasetBackup.request;
  };
}

This uses the dataset backup contract which is exposed through the ZFS module’s shb.zfs.pools.<name>.datasets.<name>.datasetBackup option.

Custom Template

Create a custom template and use it:

{
  shb.zfs.pools.root.datasets.home = {
    path = "/home";
  };

  services.sanoid.templates."yearly" = {
    hourly = 10;
    daily = 3;
    monthly = 3;
    yearly = 2;
  };

  shb.sanoid.backup."root/home" = {
    request = shb.zfs.pools.root.datasets.home.datasetBackup.request;
    template = "yearly";
  };
}

Note we use the upstream services.sanoid.templates option to define the templates.

Without contract

To backup a dataset that does not provide the dataset backup contract, we can just set the request manually:

{
  shb.zfs.pools.root.datasets.home = {
    path = "/home";
  };

  shb.sanoid.backup."root/home" = {
    request.dataset = "root/home";
  };
}

Note the attr name under the shb.sanoid.backup option does not set the dataset name.

Best Practices

Let’s assume you have a few datasets you want to backup on one hard drive, say root/safe/home and data/nextcloud and and a destination dataset on a second hard drive where backups will be sent for replication, say backup/syncoid.

The following configuration creates a new snapshot every hour on the root/safe/home and data/nextcloud dataset and keeps:

  • the last 5 hourly snapshots

  • one snapshot per day for the last 10 days

  • one snapshot per month for the last 15 months

  • one snapshot per year for the last 20 years

The same configuration is set for the backup/syncoid dataset.

{
  services.sanoid = {
    enable = true;
    templates.main = {
      autosnap = true;
      autoprune = true;
      hourly = 5;
      daily = 10;
      monthly = 15;
      yearly = 20;
    };
    templates.backup = {
      autosnap = false;
      autoprune = true;
      hourly = 5;
      daily = 10;
      monthly = 15;
      yearly = 20;
    };
  };

  shb.zfs.pools.data.datasets."nextcloud".path = "/var/lib/nextcloud";
  shb.sanoid.backup."data/nextcloud" = {
    request = config.shb.zfs.pools.data.datasets."nextcloud".datasetBackup.request;
    settings.useTemplate = [ "main" ];
  };

  shb.zfs.pools.root.datasets."safe/home".path = "/home";
  shb.sanoid.backup."root/safe/home" = {
    request = config.shb.zfs.pools.root.datasets."safe/home".datasetBackup.request;
    settings.useTemplate = [ "main" ];
  };

  services.syncoid = {
    enable = true;

    commands."root/safe/home" = {
      recursive = true;
      target = "backup/syncoid/root/safe/home";
      extraArgs = [
        "--create-bookmark"
        "--no-sync-snap"
      ];
    };

    commands."data/nextcloud" = {
      recursive = true;
      target = "backup/syncoid/data/nextcloud";
      extraArgs = [
        "--create-bookmark"
        "--no-sync-snap"
      ];
    };
  };

  shb.zfs.pools.backup.datasets."syncoid".path = "none";
  shb.sanoid.backup."backup/syncoid" = {
    request = config.shb.zfs.pools.backup.datasets."syncoid".datasetBackup.request;
    settings.useTemplate = [ "backup" ];
  };
}

Options Reference

shb.sanoid.backup

Sanoid prodiver for file backup contract

Type: attribute set of (submodule)

Default:

{ }

Declared by:

<selfhostblocks/modules/blocks/sanoid.nix>
shb.sanoid.backup.<name>.request

Request part of the backup contract.

Options set by the requester module enforcing how to backup files.

Type: submodule

Default:

""

Declared by:

<selfhostblocks/modules/blocks/sanoid.nix>
shb.sanoid.backup.<name>.request.excludePatterns

File patterns to exclude.

Type: list of string

Default:

[ ]

Declared by:

<selfhostblocks/modules/blocks/sanoid.nix>
shb.sanoid.backup.<name>.request.hooks

Hooks to run around the backup.

Type: submodule

Default:

{ }

Declared by:

<selfhostblocks/modules/blocks/sanoid.nix>
shb.sanoid.backup.<name>.request.hooks.afterBackup

Hooks to run after backup.

Type: list of string

Default:

[ ]

Declared by:

<selfhostblocks/modules/blocks/sanoid.nix>
shb.sanoid.backup.<name>.request.hooks.beforeBackup

Hooks to run before backup.

Type: list of string

Default:

[ ]

Declared by:

<selfhostblocks/modules/blocks/sanoid.nix>
shb.sanoid.backup.<name>.request.sourceDirectories

Directories to backup.

Type: non-empty (list of string)

Default:

[
  "/var/lib/example"
]

Example:

"/var/lib/vaultwarden"

Declared by:

<selfhostblocks/modules/blocks/sanoid.nix>
shb.sanoid.backup.<name>.request.user

Unix user doing the backups.

Type: string

Default:

""

Example:

"vaultwarden"

Declared by:

<selfhostblocks/modules/blocks/sanoid.nix>
shb.sanoid.backup.<name>.result

Result part of the backup contract.

Options set by the provider module that indicates the name of the backup and restore scripts.

Type: submodule

Default: { restoreScript = sanoid-\x3cname\x3e-restore; backupService = sanoid.service; }

Declared by:

<selfhostblocks/modules/blocks/sanoid.nix>
shb.sanoid.backup.<name>.result.backupService

Name of service backing up the database.

This script can be ran manually to backup the database:

$ systemctl start sanoid.service

Type: string

Default: sanoid.service

Declared by:

<selfhostblocks/modules/blocks/sanoid.nix>
shb.sanoid.backup.<name>.result.restoreScript

Name of script that can restore the database. One can then list snapshots with:

$ sanoid-\x3cname\x3e-restore snapshots
<snapshot 1> <metadata>
<snapshot 2> <metadata>

And restore the database with:

$ sanoid-\x3cname\x3e-restore restore <snapshot 1>

Type: string

Default: sanoid-\x3cname\x3e-restore

Declared by:

<selfhostblocks/modules/blocks/sanoid.nix>
shb.sanoid.backup.<name>.settings

Options passed to the services.sanoid.datasets.<name> option.

Type: attribute set of anything

Default:

{ }

Declared by:

<selfhostblocks/modules/blocks/sanoid.nix>