summary refs log tree commit diff
path: root/nixos/modules/services/backup
diff options
context:
space:
mode:
authorpennae <82953136+pennae@users.noreply.github.com>2022-08-02 02:15:30 +0200
committerGitHub <noreply@github.com>2022-08-02 02:15:30 +0200
commit6b13dd0e9e7e0097bf796394386f0e88c33b172e (patch)
tree73e0673bf60b7add5ef30079e98ab26d8984787a /nixos/modules/services/backup
parent6aefb1d58968ee8991d1c67d459c41924338e68f (diff)
parent2e751c0772b9d48ff6923569adfa661b030ab6a2 (diff)
Merge pull request #183491 from pennae/automatic-md-conversions
treewide: automatically md-convert option descriptions
Diffstat (limited to 'nixos/modules/services/backup')
-rw-r--r--nixos/modules/services/backup/automysqlbackup.nix6
-rw-r--r--nixos/modules/services/backup/bacula.nix80
-rw-r--r--nixos/modules/services/backup/borgbackup.nix174
-rw-r--r--nixos/modules/services/backup/borgmatic.nix6
-rw-r--r--nixos/modules/services/backup/btrbk.nix18
-rw-r--r--nixos/modules/services/backup/duplicati.nix6
-rw-r--r--nixos/modules/services/backup/duplicity.nix14
-rw-r--r--nixos/modules/services/backup/mysql-backup.nix10
-rw-r--r--nixos/modules/services/backup/postgresql-backup.nix20
-rw-r--r--nixos/modules/services/backup/postgresql-wal-receiver.nix50
-rw-r--r--nixos/modules/services/backup/restic-rest-server.nix14
-rw-r--r--nixos/modules/services/backup/restic.nix54
-rw-r--r--nixos/modules/services/backup/rsnapshot.nix6
-rw-r--r--nixos/modules/services/backup/sanoid.nix32
-rw-r--r--nixos/modules/services/backup/syncoid.nix64
-rw-r--r--nixos/modules/services/backup/tarsnap.nix74
-rw-r--r--nixos/modules/services/backup/tsm.nix24
-rw-r--r--nixos/modules/services/backup/zfs-replication.nix14
-rw-r--r--nixos/modules/services/backup/znapzend.nix72
-rw-r--r--nixos/modules/services/backup/zrepl.nix2
20 files changed, 370 insertions, 370 deletions
diff --git a/nixos/modules/services/backup/automysqlbackup.nix b/nixos/modules/services/backup/automysqlbackup.nix
index cf0cb4da32cf1..194b49da539aa 100644
--- a/nixos/modules/services/backup/automysqlbackup.nix
+++ b/nixos/modules/services/backup/automysqlbackup.nix
@@ -35,7 +35,7 @@ in
       calendar = mkOption {
         type = types.str;
         default = "01:15:00";
-        description = ''
+        description = lib.mdDoc ''
           Configured when to run the backup service systemd unit (DayOfWeek Year-Month-Day Hour:Minute:Second).
         '';
       };
@@ -43,9 +43,9 @@ in
       config = mkOption {
         type = with types; attrsOf (oneOf [ str int bool (listOf str) ]);
         default = {};
-        description = ''
+        description = lib.mdDoc ''
           automysqlbackup configuration. Refer to
-          <filename>''${pkgs.automysqlbackup}/etc/automysqlbackup.conf</filename>
+          {file}`''${pkgs.automysqlbackup}/etc/automysqlbackup.conf`
           for details on supported values.
         '';
         example = literalExpression ''
diff --git a/nixos/modules/services/backup/bacula.nix b/nixos/modules/services/backup/bacula.nix
index 5989020423463..cb8a6eb4390c8 100644
--- a/nixos/modules/services/backup/bacula.nix
+++ b/nixos/modules/services/backup/bacula.nix
@@ -114,7 +114,7 @@ let
       password = mkOption {
         type = types.str;
         # TODO: required?
-        description = ''
+        description = lib.mdDoc ''
           Specifies the password that must be supplied for the default Bacula
           Console to be authorized. The same password must appear in the
           Director resource of the Console configuration file. For added
@@ -135,10 +135,10 @@ let
         type = types.enum [ "no" "yes" ];
         default = "no";
         example = "yes";
-        description = ''
-          If Monitor is set to <literal>no</literal>, this director will have
+        description = lib.mdDoc ''
+          If Monitor is set to `no`, this director will have
           full access to this Storage daemon. If Monitor is set to
-          <literal>yes</literal>, this director will only be able to fetch the
+          `yes`, this director will only be able to fetch the
           current status of this Storage daemon.
 
           Please note that if this director is being used by a Monitor, we
@@ -154,15 +154,15 @@ let
     options = {
       changerDevice = mkOption {
         type = types.str;
-        description = ''
+        description = lib.mdDoc ''
           The specified name-string must be the generic SCSI device name of the
           autochanger that corresponds to the normal read/write Archive Device
           specified in the Device resource. This generic SCSI device name
           should be specified if you have an autochanger or if you have a
           standard tape drive and want to use the Alert Command (see below).
           For example, on Linux systems, for an Archive Device name of
-          <literal>/dev/nst0</literal>, you would specify
-          <literal>/dev/sg0</literal> for the Changer Device name.  Depending
+          `/dev/nst0`, you would specify
+          `/dev/sg0` for the Changer Device name.  Depending
           on your exact configuration, and the number of autochangers or the
           type of autochanger, what you specify here can vary. This directive
           is optional. See the Using AutochangersAutochangersChapter chapter of
@@ -173,7 +173,7 @@ let
 
       changerCommand = mkOption {
         type = types.str;
-        description = ''
+        description = lib.mdDoc ''
           The name-string specifies an external program to be called that will
           automatically change volumes as required by Bacula. Normally, this
           directive will be specified only in the AutoChanger resource, which
@@ -181,7 +181,7 @@ let
           different Changer Command in each Device resource. Most frequently,
           you will specify the Bacula supplied mtx-changer script as follows:
 
-          <literal>"/path/mtx-changer %c %o %S %a %d"</literal>
+          `"/path/mtx-changer %c %o %S %a %d"`
 
           and you will install the mtx on your system (found in the depkgs
           release). An example of this command is in the default bacula-sd.conf
@@ -202,7 +202,7 @@ let
       extraAutochangerConfig = mkOption {
         default = "";
         type = types.lines;
-        description = ''
+        description = lib.mdDoc ''
           Extra configuration to be passed in Autochanger directive.
         '';
         example = ''
@@ -219,13 +219,13 @@ let
       archiveDevice = mkOption {
         # TODO: required?
         type = types.str;
-        description = ''
+        description = lib.mdDoc ''
           The specified name-string gives the system file name of the storage
           device managed by this storage daemon. This will usually be the
           device file name of a removable storage device (tape drive), for
-          example <literal>/dev/nst0</literal> or
-          <literal>/dev/rmt/0mbn</literal>. For a DVD-writer, it will be for
-          example <literal>/dev/hdc</literal>. It may also be a directory name
+          example `/dev/nst0` or
+          `/dev/rmt/0mbn`. For a DVD-writer, it will be for
+          example `/dev/hdc`. It may also be a directory name
           if you are archiving to disk storage. In this case, you must supply
           the full absolute path to the directory. When specifying a tape
           device, it is preferable that the "non-rewind" variant of the device
@@ -236,9 +236,9 @@ let
       mediaType = mkOption {
         # TODO: required?
         type = types.str;
-        description = ''
+        description = lib.mdDoc ''
           The specified name-string names the type of media supported by this
-          device, for example, <literal>DLT7000</literal>. Media type names are
+          device, for example, `DLT7000`. Media type names are
           arbitrary in that you set them to anything you want, but they must be
           known to the volume database to keep track of which storage daemons
           can read which volumes. In general, each different storage type
@@ -255,9 +255,9 @@ let
           Storage daemon, but it is with multiple Storage daemons, especially
           if they have incompatible media.
 
-          For example, if you specify a Media Type of <literal>DDS-4</literal>
+          For example, if you specify a Media Type of `DDS-4`
           then during the restore, Bacula will be able to choose any Storage
-          Daemon that handles <literal>DDS-4</literal>. If you have an
+          Daemon that handles `DDS-4`. If you have an
           autochanger, you might want to name the Media Type in a way that is
           unique to the autochanger, unless you wish to possibly use the
           Volumes in other drives. You should also ensure to have unique Media
@@ -274,7 +274,7 @@ let
       extraDeviceConfig = mkOption {
         default = "";
         type = types.lines;
-        description = ''
+        description = lib.mdDoc ''
           Extra configuration to be passed in Device directive.
         '';
         example = ''
@@ -295,7 +295,7 @@ in {
       enable = mkOption {
         type = types.bool;
         default = false;
-        description = ''
+        description = lib.mdDoc ''
           Whether to enable the Bacula File Daemon.
         '';
       };
@@ -304,7 +304,7 @@ in {
         default = "${config.networking.hostName}-fd";
         defaultText = literalExpression ''"''${config.networking.hostName}-fd"'';
         type = types.str;
-        description = ''
+        description = lib.mdDoc ''
           The client name that must be used by the Director when connecting.
           Generally, it is a good idea to use a name related to the machine so
           that error messages can be easily identified if you have multiple
@@ -315,7 +315,7 @@ in {
       port = mkOption {
         default = 9102;
         type = types.int;
-        description = ''
+        description = lib.mdDoc ''
           This specifies the port number on which the Client listens for
           Director connections. It must agree with the FDPort specified in
           the Client resource of the Director's configuration file.
@@ -324,7 +324,7 @@ in {
 
       director = mkOption {
         default = {};
-        description = ''
+        description = lib.mdDoc ''
           This option defines director resources in Bacula File Daemon.
         '';
         type = with types; attrsOf (submodule directorOptions);
@@ -333,7 +333,7 @@ in {
       extraClientConfig = mkOption {
         default = "";
         type = types.lines;
-        description = ''
+        description = lib.mdDoc ''
           Extra configuration to be passed in Client directive.
         '';
         example = ''
@@ -345,7 +345,7 @@ in {
       extraMessagesConfig = mkOption {
         default = "";
         type = types.lines;
-        description = ''
+        description = lib.mdDoc ''
           Extra configuration to be passed in Messages directive.
         '';
         example = ''
@@ -358,7 +358,7 @@ in {
       enable = mkOption {
         type = types.bool;
         default = false;
-        description = ''
+        description = lib.mdDoc ''
           Whether to enable Bacula Storage Daemon.
         '';
       };
@@ -367,7 +367,7 @@ in {
         default = "${config.networking.hostName}-sd";
         defaultText = literalExpression ''"''${config.networking.hostName}-sd"'';
         type = types.str;
-        description = ''
+        description = lib.mdDoc ''
           Specifies the Name of the Storage daemon.
         '';
       };
@@ -375,7 +375,7 @@ in {
       port = mkOption {
         default = 9103;
         type = types.int;
-        description = ''
+        description = lib.mdDoc ''
           Specifies port number on which the Storage daemon listens for
           Director connections.
         '';
@@ -383,7 +383,7 @@ in {
 
       director = mkOption {
         default = {};
-        description = ''
+        description = lib.mdDoc ''
           This option defines Director resources in Bacula Storage Daemon.
         '';
         type = with types; attrsOf (submodule directorOptions);
@@ -391,7 +391,7 @@ in {
 
       device = mkOption {
         default = {};
-        description = ''
+        description = lib.mdDoc ''
           This option defines Device resources in Bacula Storage Daemon.
         '';
         type = with types; attrsOf (submodule deviceOptions);
@@ -399,7 +399,7 @@ in {
 
       autochanger = mkOption {
         default = {};
-        description = ''
+        description = lib.mdDoc ''
           This option defines Autochanger resources in Bacula Storage Daemon.
         '';
         type = with types; attrsOf (submodule autochangerOptions);
@@ -408,7 +408,7 @@ in {
       extraStorageConfig = mkOption {
         default = "";
         type = types.lines;
-        description = ''
+        description = lib.mdDoc ''
           Extra configuration to be passed in Storage directive.
         '';
         example = ''
@@ -420,7 +420,7 @@ in {
       extraMessagesConfig = mkOption {
         default = "";
         type = types.lines;
-        description = ''
+        description = lib.mdDoc ''
           Extra configuration to be passed in Messages directive.
         '';
         example = ''
@@ -434,7 +434,7 @@ in {
       enable = mkOption {
         type = types.bool;
         default = false;
-        description = ''
+        description = lib.mdDoc ''
           Whether to enable Bacula Director Daemon.
         '';
       };
@@ -443,7 +443,7 @@ in {
         default = "${config.networking.hostName}-dir";
         defaultText = literalExpression ''"''${config.networking.hostName}-dir"'';
         type = types.str;
-        description = ''
+        description = lib.mdDoc ''
           The director name used by the system administrator. This directive is
           required.
         '';
@@ -452,7 +452,7 @@ in {
       port = mkOption {
         default = 9101;
         type = types.int;
-        description = ''
+        description = lib.mdDoc ''
           Specify the port (a positive integer) on which the Director daemon
           will listen for Bacula Console connections. This same port number
           must be specified in the Director resource of the Console
@@ -465,7 +465,7 @@ in {
       password = mkOption {
         # TODO: required?
         type = types.str;
-        description = ''
+        description = lib.mdDoc ''
            Specifies the password that must be supplied for a Director.
         '';
       };
@@ -473,7 +473,7 @@ in {
       extraMessagesConfig = mkOption {
         default = "";
         type = types.lines;
-        description = ''
+        description = lib.mdDoc ''
           Extra configuration to be passed in Messages directive.
         '';
         example = ''
@@ -484,7 +484,7 @@ in {
       extraDirectorConfig = mkOption {
         default = "";
         type = types.lines;
-        description = ''
+        description = lib.mdDoc ''
           Extra configuration to be passed in Director directive.
         '';
         example = ''
@@ -496,7 +496,7 @@ in {
       extraConfig = mkOption {
         default = "";
         type = types.lines;
-        description = ''
+        description = lib.mdDoc ''
           Extra configuration for Bacula Director Daemon.
         '';
         example = ''
diff --git a/nixos/modules/services/backup/borgbackup.nix b/nixos/modules/services/backup/borgbackup.nix
index 4c9ddfe4674b2..147b827497ccd 100644
--- a/nixos/modules/services/backup/borgbackup.nix
+++ b/nixos/modules/services/backup/borgbackup.nix
@@ -219,7 +219,7 @@ in {
   ###### interface
 
   options.services.borgbackup.jobs = mkOption {
-    description = ''
+    description = lib.mdDoc ''
       Deduplicating backups using BorgBackup.
       Adding a job will cause a borg-job-NAME wrapper to be added
       to your system path, so that you can perform maintenance easily.
@@ -265,9 +265,9 @@ in {
           paths = mkOption {
             type = with types; nullOr (coercedTo str lib.singleton (listOf str));
             default = null;
-            description = ''
+            description = lib.mdDoc ''
               Path(s) to back up.
-              Mutually exclusive with <option>dumpCommand</option>.
+              Mutually exclusive with {option}`dumpCommand`.
             '';
             example = "/home/user";
           };
@@ -275,42 +275,42 @@ in {
           dumpCommand = mkOption {
             type = with types; nullOr path;
             default = null;
-            description = ''
+            description = lib.mdDoc ''
               Backup the stdout of this program instead of filesystem paths.
-              Mutually exclusive with <option>paths</option>.
+              Mutually exclusive with {option}`paths`.
             '';
             example = "/path/to/createZFSsend.sh";
           };
 
           repo = mkOption {
             type = types.str;
-            description = "Remote or local repository to back up to.";
+            description = lib.mdDoc "Remote or local repository to back up to.";
             example = "user@machine:/path/to/repo";
           };
 
           removableDevice = mkOption {
             type = types.bool;
             default = false;
-            description = "Whether the repo (which must be local) is a removable device.";
+            description = lib.mdDoc "Whether the repo (which must be local) is a removable device.";
           };
 
           archiveBaseName = mkOption {
             type = types.nullOr (types.strMatching "[^/{}]+");
             default = "${globalConfig.networking.hostName}-${name}";
             defaultText = literalExpression ''"''${config.networking.hostName}-<name>"'';
-            description = ''
+            description = lib.mdDoc ''
               How to name the created archives. A timestamp, whose format is
-              determined by <option>dateFormat</option>, will be appended. The full
-              name can be modified at runtime (<literal>$archiveName</literal>).
-              Placeholders like <literal>{hostname}</literal> must not be used.
-              Use <literal>null</literal> for no base name.
+              determined by {option}`dateFormat`, will be appended. The full
+              name can be modified at runtime (`$archiveName`).
+              Placeholders like `{hostname}` must not be used.
+              Use `null` for no base name.
             '';
           };
 
           dateFormat = mkOption {
             type = types.str;
-            description = ''
-              Arguments passed to <command>date</command>
+            description = lib.mdDoc ''
+              Arguments passed to {command}`date`
               to create a timestamp suffix for the archive name.
             '';
             default = "+%Y-%m-%dT%H:%M:%S";
@@ -347,19 +347,19 @@ in {
 
           user = mkOption {
             type = types.str;
-            description = ''
-              The user <command>borg</command> is run as.
+            description = lib.mdDoc ''
+              The user {command}`borg` is run as.
               User or group need read permission
-              for the specified <option>paths</option>.
+              for the specified {option}`paths`.
             '';
             default = "root";
           };
 
           group = mkOption {
             type = types.str;
-            description = ''
+            description = lib.mdDoc ''
               The group borg is run as. User or group needs read permission
-              for the specified <option>paths</option>.
+              for the specified {option}`paths`.
             '';
             default = "root";
           };
@@ -371,20 +371,20 @@ in {
               "authenticated" "authenticated-blake2"
               "none"
             ];
-            description = ''
+            description = lib.mdDoc ''
               Encryption mode to use. Setting a mode
-              other than <literal>"none"</literal> requires
-              you to specify a <option>passCommand</option>
-              or a <option>passphrase</option>.
+              other than `"none"` requires
+              you to specify a {option}`passCommand`
+              or a {option}`passphrase`.
             '';
             example = "repokey-blake2";
           };
 
           encryption.passCommand = mkOption {
             type = with types; nullOr str;
-            description = ''
+            description = lib.mdDoc ''
               A command which prints the passphrase to stdout.
-              Mutually exclusive with <option>passphrase</option>.
+              Mutually exclusive with {option}`passphrase`.
             '';
             default = null;
             example = "cat /path/to/passphrase_file";
@@ -392,11 +392,11 @@ in {
 
           encryption.passphrase = mkOption {
             type = with types; nullOr str;
-            description = ''
+            description = lib.mdDoc ''
               The passphrase the backups are encrypted with.
-              Mutually exclusive with <option>passCommand</option>.
+              Mutually exclusive with {option}`passCommand`.
               If you do not want the passphrase to be stored in the
-              world-readable Nix store, use <option>passCommand</option>.
+              world-readable Nix store, use {option}`passCommand`.
             '';
             default = null;
           };
@@ -406,9 +406,9 @@ in {
             # compression mode must be given,
             # compression level is optional
             type = types.strMatching "none|(auto,)?(lz4|zstd|zlib|lzma)(,[[:digit:]]{1,2})?";
-            description = ''
+            description = lib.mdDoc ''
               Compression method to use. Refer to
-              <command>borg help compression</command>
+              {command}`borg help compression`
               for all available options.
             '';
             default = "lz4";
@@ -417,9 +417,9 @@ in {
 
           exclude = mkOption {
             type = with types; listOf str;
-            description = ''
+            description = lib.mdDoc ''
               Exclude paths matching any of the given patterns. See
-              <command>borg help patterns</command> for pattern syntax.
+              {command}`borg help patterns` for pattern syntax.
             '';
             default = [ ];
             example = [
@@ -430,9 +430,9 @@ in {
 
           readWritePaths = mkOption {
             type = with types; listOf path;
-            description = ''
+            description = lib.mdDoc ''
               By default, borg cannot write anywhere on the system but
-              <literal>$HOME/.config/borg</literal> and <literal>$HOME/.cache/borg</literal>.
+              `$HOME/.config/borg` and `$HOME/.cache/borg`.
               If, for example, your preHook script needs to dump files
               somewhere, put those directories here.
             '';
@@ -444,8 +444,8 @@ in {
 
           privateTmp = mkOption {
             type = types.bool;
-            description = ''
-              Set the <literal>PrivateTmp</literal> option for
+            description = lib.mdDoc ''
+              Set the `PrivateTmp` option for
               the systemd-service. Set to false if you need sockets
               or other files from global /tmp.
             '';
@@ -454,10 +454,10 @@ in {
 
           doInit = mkOption {
             type = types.bool;
-            description = ''
-              Run <command>borg init</command> if the
-              specified <option>repo</option> does not exist.
-              You should set this to <literal>false</literal>
+            description = lib.mdDoc ''
+              Run {command}`borg init` if the
+              specified {option}`repo` does not exist.
+              You should set this to `false`
               if the repository is located on an external drive
               that might not always be mounted.
             '';
@@ -466,10 +466,10 @@ in {
 
           appendFailedSuffix = mkOption {
             type = types.bool;
-            description = ''
-              Append a <literal>.failed</literal> suffix
+            description = lib.mdDoc ''
+              Append a `.failed` suffix
               to the archive name, which is only removed if
-              <command>borg create</command> has a zero exit status.
+              {command}`borg create` has a zero exit status.
             '';
             default = true;
           };
@@ -479,9 +479,9 @@ in {
             # means there is no limit of yearly archives to keep
             # The regex is for use with e.g. --keep-within 1y
             type = with types; attrsOf (either int (strMatching "[[:digit:]]+[Hdwmy]"));
-            description = ''
+            description = lib.mdDoc ''
               Prune a repository by deleting all archives not matching any of the
-              specified retention options. See <command>borg help prune</command>
+              specified retention options. See {command}`borg help prune`
               for the available options.
             '';
             default = { };
@@ -497,10 +497,10 @@ in {
 
           prune.prefix = mkOption {
             type = types.nullOr (types.str);
-            description = ''
+            description = lib.mdDoc ''
               Only consider archive names starting with this prefix for pruning.
               By default, only archives created by this job are considered.
-              Use <literal>""</literal> or <literal>null</literal> to consider all archives.
+              Use `""` or `null` to consider all archives.
             '';
             default = config.archiveBaseName;
             defaultText = literalExpression "archiveBaseName";
@@ -508,7 +508,7 @@ in {
 
           environment = mkOption {
             type = with types; attrsOf str;
-            description = ''
+            description = lib.mdDoc ''
               Environment variables passed to the backup script.
               You can for example specify which SSH key to use.
             '';
@@ -518,7 +518,7 @@ in {
 
           preHook = mkOption {
             type = types.lines;
-            description = ''
+            description = lib.mdDoc ''
               Shell commands to run before the backup.
               This can for example be used to mount file systems.
             '';
@@ -531,43 +531,43 @@ in {
 
           postInit = mkOption {
             type = types.lines;
-            description = ''
-              Shell commands to run after <command>borg init</command>.
+            description = lib.mdDoc ''
+              Shell commands to run after {command}`borg init`.
             '';
             default = "";
           };
 
           postCreate = mkOption {
             type = types.lines;
-            description = ''
-              Shell commands to run after <command>borg create</command>. The name
-              of the created archive is stored in <literal>$archiveName</literal>.
+            description = lib.mdDoc ''
+              Shell commands to run after {command}`borg create`. The name
+              of the created archive is stored in `$archiveName`.
             '';
             default = "";
           };
 
           postPrune = mkOption {
             type = types.lines;
-            description = ''
-              Shell commands to run after <command>borg prune</command>.
+            description = lib.mdDoc ''
+              Shell commands to run after {command}`borg prune`.
             '';
             default = "";
           };
 
           postHook = mkOption {
             type = types.lines;
-            description = ''
+            description = lib.mdDoc ''
               Shell commands to run just before exit. They are executed
               even if a previous command exits with a non-zero exit code.
-              The latter is available as <literal>$exitStatus</literal>.
+              The latter is available as `$exitStatus`.
             '';
             default = "";
           };
 
           extraArgs = mkOption {
             type = types.str;
-            description = ''
-              Additional arguments for all <command>borg</command> calls the
+            description = lib.mdDoc ''
+              Additional arguments for all {command}`borg` calls the
               service has. Handle with care.
             '';
             default = "";
@@ -576,9 +576,9 @@ in {
 
           extraInitArgs = mkOption {
             type = types.str;
-            description = ''
-              Additional arguments for <command>borg init</command>.
-              Can also be set at runtime using <literal>$extraInitArgs</literal>.
+            description = lib.mdDoc ''
+              Additional arguments for {command}`borg init`.
+              Can also be set at runtime using `$extraInitArgs`.
             '';
             default = "";
             example = "--append-only";
@@ -586,9 +586,9 @@ in {
 
           extraCreateArgs = mkOption {
             type = types.str;
-            description = ''
-              Additional arguments for <command>borg create</command>.
-              Can also be set at runtime using <literal>$extraCreateArgs</literal>.
+            description = lib.mdDoc ''
+              Additional arguments for {command}`borg create`.
+              Can also be set at runtime using `$extraCreateArgs`.
             '';
             default = "";
             example = "--stats --checkpoint-interval 600";
@@ -596,9 +596,9 @@ in {
 
           extraPruneArgs = mkOption {
             type = types.str;
-            description = ''
-              Additional arguments for <command>borg prune</command>.
-              Can also be set at runtime using <literal>$extraPruneArgs</literal>.
+            description = lib.mdDoc ''
+              Additional arguments for {command}`borg prune`.
+              Can also be set at runtime using `$extraPruneArgs`.
             '';
             default = "";
             example = "--save-space";
@@ -610,12 +610,12 @@ in {
   };
 
   options.services.borgbackup.repos = mkOption {
-    description = ''
+    description = lib.mdDoc ''
       Serve BorgBackup repositories to given public SSH keys,
       restricting their access to the repository only.
       See also the chapter about BorgBackup in the NixOS manual.
       Also, clients do not need to specify the absolute path when accessing the repository,
-      i.e. <literal>user@machine:.</literal> is enough. (Note colon and dot.)
+      i.e. `user@machine:.` is enough. (Note colon and dot.)
     '';
     default = { };
     type = types.attrsOf (types.submodule (
@@ -623,7 +623,7 @@ in {
         options = {
           path = mkOption {
             type = types.path;
-            description = ''
+            description = lib.mdDoc ''
               Where to store the backups. Note that the directory
               is created automatically, with correct permissions.
             '';
@@ -632,30 +632,30 @@ in {
 
           user = mkOption {
             type = types.str;
-            description = ''
-              The user <command>borg serve</command> is run as.
+            description = lib.mdDoc ''
+              The user {command}`borg serve` is run as.
               User or group needs write permission
-              for the specified <option>path</option>.
+              for the specified {option}`path`.
             '';
             default = "borg";
           };
 
           group = mkOption {
             type = types.str;
-            description = ''
-              The group <command>borg serve</command> is run as.
+            description = lib.mdDoc ''
+              The group {command}`borg serve` is run as.
               User or group needs write permission
-              for the specified <option>path</option>.
+              for the specified {option}`path`.
             '';
             default = "borg";
           };
 
           authorizedKeys = mkOption {
             type = with types; listOf str;
-            description = ''
+            description = lib.mdDoc ''
               Public SSH keys that are given full write access to this repository.
               You should use a different SSH key for each repository you write to, because
-              the specified keys are restricted to running <command>borg serve</command>
+              the specified keys are restricted to running {command}`borg serve`
               and can only access this single repository.
             '';
             default = [ ];
@@ -663,7 +663,7 @@ in {
 
           authorizedKeysAppendOnly = mkOption {
             type = with types; listOf str;
-            description = ''
+            description = lib.mdDoc ''
               Public SSH keys that can only be used to append new data (archives) to the repository.
               Note that archives can still be marked as deleted and are subsequently removed from disk
               upon accessing the repo with full write access, e.g. when pruning.
@@ -673,11 +673,11 @@ in {
 
           allowSubRepos = mkOption {
             type = types.bool;
-            description = ''
+            description = lib.mdDoc ''
               Allow clients to create repositories in subdirectories of the
-              specified <option>path</option>. These can be accessed using
-              <literal>user@machine:path/to/subrepo</literal>. Note that a
-              <option>quota</option> applies to repositories independently.
+              specified {option}`path`. These can be accessed using
+              `user@machine:path/to/subrepo`. Note that a
+              {option}`quota` applies to repositories independently.
               Therefore, if this is enabled, clients can create multiple
               repositories and upload an arbitrary amount of data.
             '';
@@ -687,9 +687,9 @@ in {
           quota = mkOption {
             # See the definition of parse_file_size() in src/borg/helpers/parseformat.py
             type = with types; nullOr (strMatching "[[:digit:].]+[KMGTP]?");
-            description = ''
+            description = lib.mdDoc ''
               Storage quota for the repository. This quota is ensured for all
-              sub-repositories if <option>allowSubRepos</option> is enabled
+              sub-repositories if {option}`allowSubRepos` is enabled
               but not for the overall storage space used.
             '';
             default = null;
diff --git a/nixos/modules/services/backup/borgmatic.nix b/nixos/modules/services/backup/borgmatic.nix
index 9414d78aa751d..7236a1f194115 100644
--- a/nixos/modules/services/backup/borgmatic.nix
+++ b/nixos/modules/services/backup/borgmatic.nix
@@ -11,7 +11,7 @@ in {
     enable = mkEnableOption "borgmatic";
 
     settings = mkOption {
-      description = ''
+      description = lib.mdDoc ''
         See https://torsion.org/borgmatic/docs/reference/configuration/
       '';
       type = types.submodule {
@@ -19,7 +19,7 @@ in {
         options.location = {
           source_directories = mkOption {
             type = types.listOf types.str;
-            description = ''
+            description = lib.mdDoc ''
               List of source directories to backup (required). Globs and
               tildes are expanded.
             '';
@@ -27,7 +27,7 @@ in {
           };
           repositories = mkOption {
             type = types.listOf types.str;
-            description = ''
+            description = lib.mdDoc ''
               Paths to local or remote repositories (required). Tildes are
               expanded. Multiple repositories are backed up to in
               sequence. Borg placeholders can be used. See the output of
diff --git a/nixos/modules/services/backup/btrbk.nix b/nixos/modules/services/backup/btrbk.nix
index e17761ffc3cb9..f1d58f597c255 100644
--- a/nixos/modules/services/backup/btrbk.nix
+++ b/nixos/modules/services/backup/btrbk.nix
@@ -74,23 +74,23 @@ in
   options = {
     services.btrbk = {
       extraPackages = mkOption {
-        description = "Extra packages for btrbk, like compression utilities for <literal>stream_compress</literal>";
+        description = lib.mdDoc "Extra packages for btrbk, like compression utilities for `stream_compress`";
         type = types.listOf types.package;
         default = [ ];
         example = literalExpression "[ pkgs.xz ]";
       };
       niceness = mkOption {
-        description = "Niceness for local instances of btrbk. Also applies to remote ones connecting via ssh when positive.";
+        description = lib.mdDoc "Niceness for local instances of btrbk. Also applies to remote ones connecting via ssh when positive.";
         type = types.ints.between (-20) 19;
         default = 10;
       };
       ioSchedulingClass = mkOption {
-        description = "IO scheduling class for btrbk (see ionice(1) for a quick description). Applies to local instances, and remote ones connecting by ssh if set to idle.";
+        description = lib.mdDoc "IO scheduling class for btrbk (see ionice(1) for a quick description). Applies to local instances, and remote ones connecting by ssh if set to idle.";
         type = types.enum [ "idle" "best-effort" "realtime" ];
         default = "best-effort";
       };
       instances = mkOption {
-        description = "Set of btrbk instances. The instance named <literal>btrbk</literal> is the default one.";
+        description = lib.mdDoc "Set of btrbk instances. The instance named `btrbk` is the default one.";
         type = with types;
           attrsOf (
             submodule {
@@ -98,7 +98,7 @@ in
                 onCalendar = mkOption {
                   type = types.nullOr types.str;
                   default = "daily";
-                  description = ''
+                  description = lib.mdDoc ''
                     How often this btrbk instance is started. See systemd.time(7) for more information about the format.
                     Setting it to null disables the timer, thus this instance can only be started manually.
                   '';
@@ -119,7 +119,7 @@ in
                       };
                     };
                   };
-                  description = "configuration options for btrbk. Nested attrsets translate to subsections.";
+                  description = lib.mdDoc "configuration options for btrbk. Nested attrsets translate to subsections.";
                 };
               };
             }
@@ -127,18 +127,18 @@ in
         default = { };
       };
       sshAccess = mkOption {
-        description = "SSH keys that should be able to make or push snapshots on this system remotely with btrbk";
+        description = lib.mdDoc "SSH keys that should be able to make or push snapshots on this system remotely with btrbk";
         type = with types; listOf (
           submodule {
             options = {
               key = mkOption {
                 type = str;
-                description = "SSH public key allowed to login as user <literal>btrbk</literal> to run remote backups.";
+                description = lib.mdDoc "SSH public key allowed to login as user `btrbk` to run remote backups.";
               };
               roles = mkOption {
                 type = listOf (enum [ "info" "source" "target" "delete" "snapshot" "send" "receive" ]);
                 example = [ "source" "info" "send" ];
-                description = "What actions can be performed with this SSH key. See ssh_filter_btrbk(1) for details";
+                description = lib.mdDoc "What actions can be performed with this SSH key. See ssh_filter_btrbk(1) for details";
               };
             };
           }
diff --git a/nixos/modules/services/backup/duplicati.nix b/nixos/modules/services/backup/duplicati.nix
index 97864c44691b0..8da29a04c824b 100644
--- a/nixos/modules/services/backup/duplicati.nix
+++ b/nixos/modules/services/backup/duplicati.nix
@@ -13,7 +13,7 @@ in
       port = mkOption {
         default = 8200;
         type = types.int;
-        description = ''
+        description = lib.mdDoc ''
           Port serving the web interface
         '';
       };
@@ -35,7 +35,7 @@ in
       interface = mkOption {
         default = "127.0.0.1";
         type = types.str;
-        description = ''
+        description = lib.mdDoc ''
           Listening interface for the web UI
           Set it to "any" to listen on all available interfaces
         '';
@@ -44,7 +44,7 @@ in
       user = mkOption {
         default = "duplicati";
         type = types.str;
-        description = ''
+        description = lib.mdDoc ''
           Duplicati runs as it's own user. It will only be able to backup world-readable files.
           Run as root with special care.
         '';
diff --git a/nixos/modules/services/backup/duplicity.nix b/nixos/modules/services/backup/duplicity.nix
index 6949fa8b995c0..8c41059555693 100644
--- a/nixos/modules/services/backup/duplicity.nix
+++ b/nixos/modules/services/backup/duplicity.nix
@@ -18,7 +18,7 @@ in
     root = mkOption {
       type = types.path;
       default = "/";
-      description = ''
+      description = lib.mdDoc ''
         Root directory to backup.
       '';
     };
@@ -96,10 +96,10 @@ in
       type = types.str;
       default = "never";
       example = "1M";
-      description = ''
-        If <literal>"never"</literal> (the default) always do incremental
+      description = lib.mdDoc ''
+        If `"never"` (the default) always do incremental
         backups (the first backup will be a full backup, of course).  If
-        <literal>"always"</literal> always do full backups.  Otherwise, this
+        `"always"` always do full backups.  Otherwise, this
         must be a string representing a duration. Full backups will be made
         when the latest full backup is older than this duration. If this is not
         the case, an incremental backup is performed.
@@ -111,7 +111,7 @@ in
         type = types.nullOr types.str;
         default = null;
         example = "6M";
-        description = ''
+        description = lib.mdDoc ''
           If non-null, delete all backup sets older than the given time.  Old backup sets
           will not be deleted if backup sets newer than time depend on them.
         '';
@@ -120,7 +120,7 @@ in
         type = types.nullOr types.int;
         default = null;
         example = 2;
-        description = ''
+        description = lib.mdDoc ''
           If non-null, delete all backups sets that are older than the count:th last full
           backup (in other words, keep the last count full backups and
           associated incremental sets).
@@ -130,7 +130,7 @@ in
         type = types.nullOr types.int;
         default = null;
         example = 1;
-        description = ''
+        description = lib.mdDoc ''
           If non-null, delete incremental sets of all backups sets that are
           older than the count:th last full backup (in other words, keep only
           old full backups and not their increments).
diff --git a/nixos/modules/services/backup/mysql-backup.nix b/nixos/modules/services/backup/mysql-backup.nix
index c40a0b5abc40e..41adb63e7fa8d 100644
--- a/nixos/modules/services/backup/mysql-backup.nix
+++ b/nixos/modules/services/backup/mysql-backup.nix
@@ -42,7 +42,7 @@ in
       calendar = mkOption {
         type = types.str;
         default = "01:15:00";
-        description = ''
+        description = lib.mdDoc ''
           Configured when to run the backup service systemd unit (DayOfWeek Year-Month-Day Hour:Minute:Second).
         '';
       };
@@ -50,7 +50,7 @@ in
       user = mkOption {
         type = types.str;
         default = defaultUser;
-        description = ''
+        description = lib.mdDoc ''
           User to be used to perform backup.
         '';
       };
@@ -58,7 +58,7 @@ in
       databases = mkOption {
         default = [];
         type = types.listOf types.str;
-        description = ''
+        description = lib.mdDoc ''
           List of database names to dump.
         '';
       };
@@ -66,7 +66,7 @@ in
       location = mkOption {
         type = types.path;
         default = "/var/backup/mysql";
-        description = ''
+        description = lib.mdDoc ''
           Location to put the gzipped MySQL database dumps.
         '';
       };
@@ -74,7 +74,7 @@ in
       singleTransaction = mkOption {
         default = false;
         type = types.bool;
-        description = ''
+        description = lib.mdDoc ''
           Whether to create database dump in a single transaction
         '';
       };
diff --git a/nixos/modules/services/backup/postgresql-backup.nix b/nixos/modules/services/backup/postgresql-backup.nix
index f22b613382734..744ccb98e2c2b 100644
--- a/nixos/modules/services/backup/postgresql-backup.nix
+++ b/nixos/modules/services/backup/postgresql-backup.nix
@@ -76,8 +76,8 @@ in {
       startAt = mkOption {
         default = "*-*-* 01:15:00";
         type = with types; either (listOf str) str;
-        description = ''
-          This option defines (see <literal>systemd.time</literal> for format) when the
+        description = lib.mdDoc ''
+          This option defines (see `systemd.time` for format) when the
           databases should be dumped.
           The default is to update at 01:15 (at night) every day.
         '';
@@ -87,10 +87,10 @@ in {
         default = cfg.databases == [];
         defaultText = literalExpression "services.postgresqlBackup.databases == []";
         type = lib.types.bool;
-        description = ''
+        description = lib.mdDoc ''
           Backup all databases using pg_dumpall.
           This option is mutual exclusive to
-          <literal>services.postgresqlBackup.databases</literal>.
+          `services.postgresqlBackup.databases`.
           The resulting backup dump will have the name all.sql.gz.
           This option is the default if no databases are specified.
         '';
@@ -99,7 +99,7 @@ in {
       databases = mkOption {
         default = [];
         type = types.listOf types.str;
-        description = ''
+        description = lib.mdDoc ''
           List of database names to dump.
         '';
       };
@@ -107,7 +107,7 @@ in {
       location = mkOption {
         default = "/var/backup/postgresql";
         type = types.path;
-        description = ''
+        description = lib.mdDoc ''
           Path of directory where the PostgreSQL database dumps will be placed.
         '';
       };
@@ -115,9 +115,9 @@ in {
       pgdumpOptions = mkOption {
         type = types.separatedString " ";
         default = "-C";
-        description = ''
+        description = lib.mdDoc ''
           Command line options for pg_dump. This options is not used
-          if <literal>config.services.postgresqlBackup.backupAll</literal> is enabled.
+          if `config.services.postgresqlBackup.backupAll` is enabled.
           Note that config.services.postgresqlBackup.backupAll is also active,
           when no databases where specified.
         '';
@@ -126,7 +126,7 @@ in {
       compression = mkOption {
         type = types.enum ["none" "gzip" "zstd"];
         default = "gzip";
-        description = ''
+        description = lib.mdDoc ''
           The type of compression to use on the generated database dump.
         '';
       };
@@ -134,7 +134,7 @@ in {
       compressionLevel = mkOption {
         type = types.ints.between 1 19;
         default = 6;
-        description = ''
+        description = lib.mdDoc ''
           The compression level used when compression is enabled.
           gzip accepts levels 1 to 9. zstd accepts levels 1 to 19.
         '';
diff --git a/nixos/modules/services/backup/postgresql-wal-receiver.nix b/nixos/modules/services/backup/postgresql-wal-receiver.nix
index 32643adfdaeac..01fd57f5c5062 100644
--- a/nixos/modules/services/backup/postgresql-wal-receiver.nix
+++ b/nixos/modules/services/backup/postgresql-wal-receiver.nix
@@ -8,7 +8,7 @@ let
       postgresqlPackage = mkOption {
         type = types.package;
         example = literalExpression "pkgs.postgresql_11";
-        description = ''
+        description = lib.mdDoc ''
           PostgreSQL package to use.
         '';
       };
@@ -16,7 +16,7 @@ let
       directory = mkOption {
         type = types.path;
         example = literalExpression "/mnt/pg_wal/main/";
-        description = ''
+        description = lib.mdDoc ''
           Directory to write the output to.
         '';
       };
@@ -24,7 +24,7 @@ let
       statusInterval = mkOption {
         type = types.int;
         default = 10;
-        description = ''
+        description = lib.mdDoc ''
           Specifies the number of seconds between status packets sent back to the server.
           This allows for easier monitoring of the progress from server.
           A value of zero disables the periodic status updates completely,
@@ -36,27 +36,27 @@ let
         type = types.str;
         default = "";
         example = "some_slot_name";
-        description = ''
-          Require <command>pg_receivewal</command> to use an existing replication slot (see
-          <link xlink:href="https://www.postgresql.org/docs/current/warm-standby.html#STREAMING-REPLICATION-SLOTS">Section 26.2.6 of the PostgreSQL manual</link>).
-          When this option is used, <command>pg_receivewal</command> will report a flush position to the server,
+        description = lib.mdDoc ''
+          Require {command}`pg_receivewal` to use an existing replication slot (see
+          [Section 26.2.6 of the PostgreSQL manual](https://www.postgresql.org/docs/current/warm-standby.html#STREAMING-REPLICATION-SLOTS)).
+          When this option is used, {command}`pg_receivewal` will report a flush position to the server,
           indicating when each segment has been synchronized to disk so that the server can remove that segment if it is not otherwise needed.
 
-          When the replication client of <command>pg_receivewal</command> is configured on the server as a synchronous standby,
+          When the replication client of {command}`pg_receivewal` is configured on the server as a synchronous standby,
           then using a replication slot will report the flush position to the server, but only when a WAL file is closed.
           Therefore, that configuration will cause transactions on the primary to wait for a long time and effectively not work satisfactorily.
-          The option <option>synchronous</option> must be specified in addition to make this work correctly.
+          The option {option}`synchronous` must be specified in addition to make this work correctly.
         '';
       };
 
       synchronous = mkOption {
         type = types.bool;
         default = false;
-        description = ''
+        description = lib.mdDoc ''
           Flush the WAL data to disk immediately after it has been received.
-          Also send a status packet back to the server immediately after flushing, regardless of <option>statusInterval</option>.
+          Also send a status packet back to the server immediately after flushing, regardless of {option}`statusInterval`.
 
-          This option should be specified if the replication client of <command>pg_receivewal</command> is configured on the server as a synchronous standby,
+          This option should be specified if the replication client of {command}`pg_receivewal` is configured on the server as a synchronous standby,
           to ensure that timely feedback is sent to the server.
         '';
       };
@@ -64,10 +64,10 @@ let
       compress = mkOption {
         type = types.ints.between 0 9;
         default = 0;
-        description = ''
+        description = lib.mdDoc ''
           Enables gzip compression of write-ahead logs, and specifies the compression level
-          (<literal>0</literal> through <literal>9</literal>, <literal>0</literal> being no compression and <literal>9</literal> being best compression).
-          The suffix <literal>.gz</literal> will automatically be added to all filenames.
+          (`0` through `9`, `0` being no compression and `9` being best compression).
+          The suffix `.gz` will automatically be added to all filenames.
 
           This option requires PostgreSQL >= 10.
         '';
@@ -76,11 +76,11 @@ let
       connection = mkOption {
         type = types.str;
         example = "postgresql://user@somehost";
-        description = ''
+        description = lib.mdDoc ''
           Specifies parameters used to connect to the server, as a connection string.
-          See <link xlink:href="https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING">Section 34.1.1 of the PostgreSQL manual</link> for more information.
+          See [Section 34.1.1 of the PostgreSQL manual](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING) for more information.
 
-          Because <command>pg_receivewal</command> doesn't connect to any particular database in the cluster,
+          Because {command}`pg_receivewal` doesn't connect to any particular database in the cluster,
           database name in the connection string will be ignored.
         '';
       };
@@ -93,8 +93,8 @@ let
             "--no-sync"
           ]
         '';
-        description = ''
-          A list of extra arguments to pass to the <command>pg_receivewal</command> command.
+        description = lib.mdDoc ''
+          A list of extra arguments to pass to the {command}`pg_receivewal` command.
         '';
       };
 
@@ -107,9 +107,9 @@ let
             PGSSLMODE = "require";
           }
         '';
-        description = ''
+        description = lib.mdDoc ''
           Environment variables passed to the service.
-          Usable parameters are listed in <link xlink:href="https://www.postgresql.org/docs/current/libpq-envars.html">Section 34.14 of the PostgreSQL manual</link>.
+          Usable parameters are listed in [Section 34.14 of the PostgreSQL manual](https://www.postgresql.org/docs/current/libpq-envars.html).
         '';
       };
     };
@@ -131,10 +131,10 @@ in {
             };
           }
         '';
-        description = ''
+        description = lib.mdDoc ''
           PostgreSQL WAL receivers.
-          Stream write-ahead logs from a PostgreSQL server using <command>pg_receivewal</command> (formerly <command>pg_receivexlog</command>).
-          See <link xlink:href="https://www.postgresql.org/docs/current/app-pgreceivewal.html">the man page</link> for more information.
+          Stream write-ahead logs from a PostgreSQL server using {command}`pg_receivewal` (formerly {command}`pg_receivexlog`).
+          See [the man page](https://www.postgresql.org/docs/current/app-pgreceivewal.html) for more information.
         '';
       };
     };
diff --git a/nixos/modules/services/backup/restic-rest-server.nix b/nixos/modules/services/backup/restic-rest-server.nix
index 4717119f178ad..1d3892c158e04 100644
--- a/nixos/modules/services/backup/restic-rest-server.nix
+++ b/nixos/modules/services/backup/restic-rest-server.nix
@@ -15,19 +15,19 @@ in
       default = ":8000";
       example = "127.0.0.1:8080";
       type = types.str;
-      description = "Listen on a specific IP address and port.";
+      description = lib.mdDoc "Listen on a specific IP address and port.";
     };
 
     dataDir = mkOption {
       default = "/var/lib/restic";
       type = types.path;
-      description = "The directory for storing the restic repository.";
+      description = lib.mdDoc "The directory for storing the restic repository.";
     };
 
     appendOnly = mkOption {
       default = false;
       type = types.bool;
-      description = ''
+      description = lib.mdDoc ''
         Enable append only mode.
         This mode allows creation of new backups but prevents deletion and modification of existing backups.
         This can be useful when backing up systems that have a potential of being hacked.
@@ -37,7 +37,7 @@ in
     privateRepos = mkOption {
       default = false;
       type = types.bool;
-      description = ''
+      description = lib.mdDoc ''
         Enable private repos.
         Grants access only when a subdirectory with the same name as the user is specified in the repository URL.
       '';
@@ -46,13 +46,13 @@ in
     prometheus = mkOption {
       default = false;
       type = types.bool;
-      description = "Enable Prometheus metrics at /metrics.";
+      description = lib.mdDoc "Enable Prometheus metrics at /metrics.";
     };
 
     extraFlags = mkOption {
       type = types.listOf types.str;
       default = [];
-      description = ''
+      description = lib.mdDoc ''
         Extra commandline options to pass to Restic REST server.
       '';
     };
@@ -61,7 +61,7 @@ in
       default = pkgs.restic-rest-server;
       defaultText = literalExpression "pkgs.restic-rest-server";
       type = types.package;
-      description = "Restic REST server package to use.";
+      description = lib.mdDoc "Restic REST server package to use.";
     };
   };
 
diff --git a/nixos/modules/services/backup/restic.nix b/nixos/modules/services/backup/restic.nix
index a0de1124c661c..76d7f093f21c0 100644
--- a/nixos/modules/services/backup/restic.nix
+++ b/nixos/modules/services/backup/restic.nix
@@ -8,14 +8,14 @@ let
 in
 {
   options.services.restic.backups = mkOption {
-    description = ''
+    description = lib.mdDoc ''
       Periodic backups to create with Restic.
     '';
     type = types.attrsOf (types.submodule ({ config, name, ... }: {
       options = {
         passwordFile = mkOption {
           type = types.str;
-          description = ''
+          description = lib.mdDoc ''
             Read the repository password from a file.
           '';
           example = "/etc/nixos/restic-password";
@@ -26,7 +26,7 @@ in
           # added on 2021-08-28, s3CredentialsFile should
           # be removed in the future (+ remember the warning)
           default = config.s3CredentialsFile;
-          description = ''
+          description = lib.mdDoc ''
             file containing the credentials to access the repository, in the
             format of an EnvironmentFile as described by systemd.exec(5)
           '';
@@ -35,7 +35,7 @@ in
         s3CredentialsFile = mkOption {
           type = with types; nullOr str;
           default = null;
-          description = ''
+          description = lib.mdDoc ''
             file containing the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
             for an S3-hosted repository, in the format of an EnvironmentFile
             as described by systemd.exec(5)
@@ -45,13 +45,13 @@ in
         rcloneOptions = mkOption {
           type = with types; nullOr (attrsOf (oneOf [ str bool ]));
           default = null;
-          description = ''
+          description = lib.mdDoc ''
             Options to pass to rclone to control its behavior.
-            See <link xlink:href="https://rclone.org/docs/#options"/> for
+            See <https://rclone.org/docs/#options> for
             available options. When specifying option names, strip the
-            leading <literal>--</literal>. To set a flag such as
-            <literal>--drive-use-trash</literal>, which does not take a value,
-            set the value to the Boolean <literal>true</literal>.
+            leading `--`. To set a flag such as
+            `--drive-use-trash`, which does not take a value,
+            set the value to the Boolean `true`.
           '';
           example = {
             bwlimit = "10M";
@@ -62,16 +62,16 @@ in
         rcloneConfig = mkOption {
           type = with types; nullOr (attrsOf (oneOf [ str bool ]));
           default = null;
-          description = ''
+          description = lib.mdDoc ''
             Configuration for the rclone remote being used for backup.
             See the remote's specific options under rclone's docs at
-            <link xlink:href="https://rclone.org/docs/"/>. When specifying
+            <https://rclone.org/docs/>. When specifying
             option names, use the "config" name specified in the docs.
-            For example, to set <literal>--b2-hard-delete</literal> for a B2
-            remote, use <literal>hard_delete = true</literal> in the
+            For example, to set `--b2-hard-delete` for a B2
+            remote, use `hard_delete = true` in the
             attribute set.
             Warning: Secrets set in here will be world-readable in the Nix
-            store! Consider using the <literal>rcloneConfigFile</literal>
+            store! Consider using the `rcloneConfigFile`
             option instead to specify secret values separately. Note that
             options set here will override those set in the config file.
           '';
@@ -86,11 +86,11 @@ in
         rcloneConfigFile = mkOption {
           type = with types; nullOr path;
           default = null;
-          description = ''
+          description = lib.mdDoc ''
             Path to the file containing rclone configuration. This file
             must contain configuration for the remote specified in this backup
             set and also must be readable by root. Options set in
-            <literal>rcloneConfig</literal> will override those set in this
+            `rcloneConfig` will override those set in this
             file.
           '';
         };
@@ -98,7 +98,7 @@ in
         repository = mkOption {
           type = with types; nullOr str;
           default = null;
-          description = ''
+          description = lib.mdDoc ''
             repository to backup to.
           '';
           example = "sftp:backup@192.168.1.100:/backups/${name}";
@@ -107,7 +107,7 @@ in
         repositoryFile = mkOption {
           type = with types; nullOr path;
           default = null;
-          description = ''
+          description = lib.mdDoc ''
             Path to the file containing the repository location to backup to.
           '';
         };
@@ -115,7 +115,7 @@ in
         paths = mkOption {
           type = types.nullOr (types.listOf types.str);
           default = null;
-          description = ''
+          description = lib.mdDoc ''
             Which paths to backup.  If null or an empty array, no
             backup command will be run.  This can be used to create a
             prune-only job.
@@ -131,7 +131,7 @@ in
           default = {
             OnCalendar = "daily";
           };
-          description = ''
+          description = lib.mdDoc ''
             When to run the backup. See man systemd.timer for details.
           '';
           example = {
@@ -143,7 +143,7 @@ in
         user = mkOption {
           type = types.str;
           default = "root";
-          description = ''
+          description = lib.mdDoc ''
             As which user the backup should run.
           '';
           example = "postgresql";
@@ -152,7 +152,7 @@ in
         extraBackupArgs = mkOption {
           type = types.listOf types.str;
           default = [ ];
-          description = ''
+          description = lib.mdDoc ''
             Extra arguments passed to restic backup.
           '';
           example = [
@@ -163,7 +163,7 @@ in
         extraOptions = mkOption {
           type = types.listOf types.str;
           default = [ ];
-          description = ''
+          description = lib.mdDoc ''
             Extra extended options to be passed to the restic --option flag.
           '';
           example = [
@@ -174,7 +174,7 @@ in
         initialize = mkOption {
           type = types.bool;
           default = false;
-          description = ''
+          description = lib.mdDoc ''
             Create the repository if it doesn't exist.
           '';
         };
@@ -199,7 +199,7 @@ in
         dynamicFilesFrom = mkOption {
           type = with types; nullOr str;
           default = null;
-          description = ''
+          description = lib.mdDoc ''
             A script that produces a list of files to back up.  The
             results of this command are given to the '--files-from'
             option.
@@ -210,7 +210,7 @@ in
         backupPrepareCommand = mkOption {
           type = with types; nullOr str;
           default = null;
-          description = ''
+          description = lib.mdDoc ''
             A script that must run before starting the backup process.
           '';
         };
@@ -218,7 +218,7 @@ in
         backupCleanupCommand = mkOption {
           type = with types; nullOr str;
           default = null;
-          description = ''
+          description = lib.mdDoc ''
             A script that must run after finishing the backup process.
           '';
         };
diff --git a/nixos/modules/services/backup/rsnapshot.nix b/nixos/modules/services/backup/rsnapshot.nix
index 6635a51ec2c65..b18c02d7d11cf 100644
--- a/nixos/modules/services/backup/rsnapshot.nix
+++ b/nixos/modules/services/backup/rsnapshot.nix
@@ -24,7 +24,7 @@ in
     services.rsnapshot = {
       enable = mkEnableOption "rsnapshot backups";
       enableManualRsnapshot = mkOption {
-        description = "Whether to enable manual usage of the rsnapshot command with this module.";
+        description = lib.mdDoc "Whether to enable manual usage of the rsnapshot command with this module.";
         default = true;
         type = types.bool;
       };
@@ -37,7 +37,7 @@ in
           backup	/home/	localhost/
         '';
         type = types.lines;
-        description = ''
+        description = lib.mdDoc ''
           rsnapshot configuration option in addition to the defaults from
           rsnapshot and this module.
 
@@ -53,7 +53,7 @@ in
         default = {};
         example = { hourly = "0 * * * *"; daily = "50 21 * * *"; };
         type = types.attrsOf types.str;
-        description = ''
+        description = lib.mdDoc ''
           Periodicity at which intervals should be run by cron.
           Note that the intervals also have to exist in configuration
           as retain options.
diff --git a/nixos/modules/services/backup/sanoid.nix b/nixos/modules/services/backup/sanoid.nix
index 5eb031b2e9f09..847b8507f7038 100644
--- a/nixos/modules/services/backup/sanoid.nix
+++ b/nixos/modules/services/backup/sanoid.nix
@@ -12,37 +12,37 @@ let
 
   commonOptions = {
     hourly = mkOption {
-      description = "Number of hourly snapshots.";
+      description = lib.mdDoc "Number of hourly snapshots.";
       type = with types; nullOr ints.unsigned;
       default = null;
     };
 
     daily = mkOption {
-      description = "Number of daily snapshots.";
+      description = lib.mdDoc "Number of daily snapshots.";
       type = with types; nullOr ints.unsigned;
       default = null;
     };
 
     monthly = mkOption {
-      description = "Number of monthly snapshots.";
+      description = lib.mdDoc "Number of monthly snapshots.";
       type = with types; nullOr ints.unsigned;
       default = null;
     };
 
     yearly = mkOption {
-      description = "Number of yearly snapshots.";
+      description = lib.mdDoc "Number of yearly snapshots.";
       type = with types; nullOr ints.unsigned;
       default = null;
     };
 
     autoprune = mkOption {
-      description = "Whether to automatically prune old snapshots.";
+      description = lib.mdDoc "Whether to automatically prune old snapshots.";
       type = with types; nullOr bool;
       default = null;
     };
 
     autosnap = mkOption {
-      description = "Whether to automatically take snapshots.";
+      description = lib.mdDoc "Whether to automatically take snapshots.";
       type = with types; nullOr bool;
       default = null;
     };
@@ -50,7 +50,7 @@ let
 
   datasetOptions = rec {
     use_template = mkOption {
-      description = "Names of the templates to use for this dataset.";
+      description = lib.mdDoc "Names of the templates to use for this dataset.";
       type = types.listOf (types.str // {
         check = (types.enum (attrNames cfg.templates)).check;
         description = "configured template name";
@@ -60,9 +60,9 @@ let
     useTemplate = use_template;
 
     recursive = mkOption {
-      description = ''
+      description = lib.mdDoc ''
         Whether to recursively snapshot dataset children.
-        You can also set this to <literal>"zfs"</literal> to handle datasets
+        You can also set this to `"zfs"` to handle datasets
         recursively in an atomic way without the possibility to
         override settings for child datasets.
       '';
@@ -71,7 +71,7 @@ let
     };
 
     process_children_only = mkOption {
-      description = "Whether to only snapshot child datasets if recursing.";
+      description = lib.mdDoc "Whether to only snapshot child datasets if recursing.";
       type = types.bool;
       default = false;
     };
@@ -135,7 +135,7 @@ in
         config.process_children_only = mkAliasDefinitions (mkDefault options.processChildrenOnly or { });
       }));
       default = { };
-      description = "Datasets to snapshot.";
+      description = lib.mdDoc "Datasets to snapshot.";
     };
 
     templates = mkOption {
@@ -144,14 +144,14 @@ in
         options = commonOptions;
       });
       default = { };
-      description = "Templates for datasets.";
+      description = lib.mdDoc "Templates for datasets.";
     };
 
     settings = mkOption {
       type = types.attrsOf datasetSettingsType;
-      description = ''
+      description = lib.mdDoc ''
         Free-form settings written directly to the config file. See
-        <link xlink:href="https://github.com/jimsalterjrs/sanoid/blob/master/sanoid.defaults.conf"/>
+        <https://github.com/jimsalterjrs/sanoid/blob/master/sanoid.defaults.conf>
         for allowed values.
       '';
     };
@@ -160,9 +160,9 @@ in
       type = types.listOf types.str;
       default = [ ];
       example = [ "--verbose" "--readonly" "--debug" ];
-      description = ''
+      description = lib.mdDoc ''
         Extra arguments to pass to sanoid. See
-        <link xlink:href="https://github.com/jimsalterjrs/sanoid/#sanoid-command-line-options"/>
+        <https://github.com/jimsalterjrs/sanoid/#sanoid-command-line-options>
         for allowed options.
       '';
     };
diff --git a/nixos/modules/services/backup/syncoid.nix b/nixos/modules/services/backup/syncoid.nix
index 4df10f5ee02bf..e53528fb66fce 100644
--- a/nixos/modules/services/backup/syncoid.nix
+++ b/nixos/modules/services/backup/syncoid.nix
@@ -102,7 +102,7 @@ in
       type = types.str;
       default = "syncoid";
       example = "backup";
-      description = ''
+      description = lib.mdDoc ''
         The user for the service. ZFS privilege delegation will be
         automatically configured for any local pools used by syncoid if this
         option is set to a user other than root. The user will be given the
@@ -116,7 +116,7 @@ in
       type = types.str;
       default = "syncoid";
       example = "backup";
-      description = "The group for the service.";
+      description = lib.mdDoc "The group for the service.";
     };
 
     sshKey = mkOption {
@@ -124,7 +124,7 @@ in
       # Prevent key from being copied to store
       apply = mapNullable toString;
       default = null;
-      description = ''
+      description = lib.mdDoc ''
         SSH private key file to use to login to the remote system. Can be
         overridden in individual commands.
       '';
@@ -134,10 +134,10 @@ in
       type = types.listOf types.str;
       # Permissions snapshot and destroy are in case --no-sync-snap is not used
       default = [ "bookmark" "hold" "send" "snapshot" "destroy" ];
-      description = ''
-        Permissions granted for the <option>services.syncoid.user</option> user
+      description = lib.mdDoc ''
+        Permissions granted for the {option}`services.syncoid.user` user
         for local source datasets. See
-        <link xlink:href="https://openzfs.github.io/openzfs-docs/man/8/zfs-allow.8.html"/>
+        <https://openzfs.github.io/openzfs-docs/man/8/zfs-allow.8.html>
         for available permissions.
       '';
     };
@@ -146,13 +146,13 @@ in
       type = types.listOf types.str;
       default = [ "change-key" "compression" "create" "mount" "mountpoint" "receive" "rollback" ];
       example = [ "create" "mount" "receive" "rollback" ];
-      description = ''
-        Permissions granted for the <option>services.syncoid.user</option> user
+      description = lib.mdDoc ''
+        Permissions granted for the {option}`services.syncoid.user` user
         for local target datasets. See
-        <link xlink:href="https://openzfs.github.io/openzfs-docs/man/8/zfs-allow.8.html"/>
+        <https://openzfs.github.io/openzfs-docs/man/8/zfs-allow.8.html>
         for available permissions.
-        Make sure to include the <literal>change-key</literal> permission if you send raw encrypted datasets,
-        the <literal>compression</literal> permission if you send raw compressed datasets, and so on.
+        Make sure to include the `change-key` permission if you send raw encrypted datasets,
+        the `compression` permission if you send raw compressed datasets, and so on.
         For remote target datasets you'll have to set your remote user permissions by yourself.
       '';
     };
@@ -161,10 +161,10 @@ in
       type = types.listOf types.str;
       default = [ ];
       example = [ "--no-sync-snap" ];
-      description = ''
+      description = lib.mdDoc ''
         Arguments to add to every syncoid command, unless disabled for that
         command. See
-        <link xlink:href="https://github.com/jimsalterjrs/sanoid/#syncoid-command-line-options"/>
+        <https://github.com/jimsalterjrs/sanoid/#syncoid-command-line-options>
         for available options.
       '';
     };
@@ -172,7 +172,7 @@ in
     service = mkOption {
       type = types.attrs;
       default = { };
-      description = ''
+      description = lib.mdDoc ''
         Systemd configuration common to all syncoid services.
       '';
     };
@@ -183,7 +183,7 @@ in
           source = mkOption {
             type = types.str;
             example = "pool/dataset";
-            description = ''
+            description = lib.mdDoc ''
               Source ZFS dataset. Can be either local or remote. Defaults to
               the attribute name.
             '';
@@ -205,32 +205,32 @@ in
             type = types.nullOr types.path;
             # Prevent key from being copied to store
             apply = mapNullable toString;
-            description = ''
+            description = lib.mdDoc ''
               SSH private key file to use to login to the remote system.
-              Defaults to <option>services.syncoid.sshKey</option> option.
+              Defaults to {option}`services.syncoid.sshKey` option.
             '';
           };
 
           localSourceAllow = mkOption {
             type = types.listOf types.str;
-            description = ''
-              Permissions granted for the <option>services.syncoid.user</option> user
+            description = lib.mdDoc ''
+              Permissions granted for the {option}`services.syncoid.user` user
               for local source datasets. See
-              <link xlink:href="https://openzfs.github.io/openzfs-docs/man/8/zfs-allow.8.html"/>
+              <https://openzfs.github.io/openzfs-docs/man/8/zfs-allow.8.html>
               for available permissions.
-              Defaults to <option>services.syncoid.localSourceAllow</option> option.
+              Defaults to {option}`services.syncoid.localSourceAllow` option.
             '';
           };
 
           localTargetAllow = mkOption {
             type = types.listOf types.str;
-            description = ''
-              Permissions granted for the <option>services.syncoid.user</option> user
+            description = lib.mdDoc ''
+              Permissions granted for the {option}`services.syncoid.user` user
               for local target datasets. See
-              <link xlink:href="https://openzfs.github.io/openzfs-docs/man/8/zfs-allow.8.html"/>
+              <https://openzfs.github.io/openzfs-docs/man/8/zfs-allow.8.html>
               for available permissions.
-              Make sure to include the <literal>change-key</literal> permission if you send raw encrypted datasets,
-              the <literal>compression</literal> permission if you send raw compressed datasets, and so on.
+              Make sure to include the `change-key` permission if you send raw encrypted datasets,
+              the `compression` permission if you send raw compressed datasets, and so on.
               For remote target datasets you'll have to set your remote user permissions by yourself.
             '';
           };
@@ -239,7 +239,7 @@ in
             type = types.separatedString " ";
             default = "";
             example = "Lc e";
-            description = ''
+            description = lib.mdDoc ''
               Advanced options to pass to zfs send. Options are specified
               without their leading dashes and separated by spaces.
             '';
@@ -249,7 +249,7 @@ in
             type = types.separatedString " ";
             default = "";
             example = "ux recordsize o compression=lz4";
-            description = ''
+            description = lib.mdDoc ''
               Advanced options to pass to zfs recv. Options are specified
               without their leading dashes and separated by spaces.
             '';
@@ -258,7 +258,7 @@ in
           useCommonArgs = mkOption {
             type = types.bool;
             default = true;
-            description = ''
+            description = lib.mdDoc ''
               Whether to add the configured common arguments to this command.
             '';
           };
@@ -266,7 +266,7 @@ in
           service = mkOption {
             type = types.attrs;
             default = { };
-            description = ''
+            description = lib.mdDoc ''
               Systemd configuration specific to this syncoid service.
             '';
           };
@@ -275,7 +275,7 @@ in
             type = types.listOf types.str;
             default = [ ];
             example = [ "--sshport 2222" ];
-            description = "Extra syncoid arguments for this command.";
+            description = lib.mdDoc "Extra syncoid arguments for this command.";
           };
         };
         config = {
@@ -291,7 +291,7 @@ in
           "pool/test".target = "root@target:pool/test";
         }
       '';
-      description = "Syncoid commands to run.";
+      description = lib.mdDoc "Syncoid commands to run.";
     };
   };
 
diff --git a/nixos/modules/services/backup/tarsnap.nix b/nixos/modules/services/backup/tarsnap.nix
index 9b5fd90012e0e..965166479be56 100644
--- a/nixos/modules/services/backup/tarsnap.nix
+++ b/nixos/modules/services/backup/tarsnap.nix
@@ -35,10 +35,10 @@ in
       keyfile = mkOption {
         type = types.str;
         default = "/root/tarsnap.key";
-        description = ''
+        description = lib.mdDoc ''
           The keyfile which associates this machine with your tarsnap
           account.
-          Create the keyfile with <command>tarsnap-keygen</command>.
+          Create the keyfile with {command}`tarsnap-keygen`.
 
           Note that each individual archive (specified below) may also have its
           own individual keyfile specified. Tarsnap does not allow multiple
@@ -47,11 +47,11 @@ in
           archives specified, you should either spread out your backups to be
           far apart, or specify a separate key for each archive. By default
           every archive defaults to using
-          <literal>"/root/tarsnap.key"</literal>.
+          `"/root/tarsnap.key"`.
 
           It's recommended for backups that you generate a key for every archive
-          using <literal>tarsnap-keygen(1)</literal>, and then generate a
-          write-only tarsnap key using <literal>tarsnap-keymgmt(1)</literal>,
+          using `tarsnap-keygen(1)`, and then generate a
+          write-only tarsnap key using `tarsnap-keymgmt(1)`,
           and keep your master key(s) for a particular machine off-site.
 
           The keyfile name should be given as a string and not a path, to
@@ -67,18 +67,18 @@ in
                 type = types.str;
                 default = gcfg.keyfile;
                 defaultText = literalExpression "config.${opt.keyfile}";
-                description = ''
+                description = lib.mdDoc ''
                   Set a specific keyfile for this archive. This defaults to
-                  <literal>"/root/tarsnap.key"</literal> if left unspecified.
+                  `"/root/tarsnap.key"` if left unspecified.
 
                   Use this option if you want to run multiple backups
                   concurrently - each archive must have a unique key. You can
                   generate a write-only key derived from your master key (which
-                  is recommended) using <literal>tarsnap-keymgmt(1)</literal>.
+                  is recommended) using `tarsnap-keymgmt(1)`.
 
                   Note: every archive must have an individual master key. You
                   must generate multiple keys with
-                  <literal>tarsnap-keygen(1)</literal>, and then generate write
+                  `tarsnap-keygen(1)`, and then generate write
                   only keys from those.
 
                   The keyfile name should be given as a string and not a path, to
@@ -92,47 +92,47 @@ in
                 defaultText = literalExpression ''
                   "/var/cache/tarsnap/''${utils.escapeSystemdPath config.${options.keyfile}}"
                 '';
-                description = ''
+                description = lib.mdDoc ''
                   The cache allows tarsnap to identify previously stored data
                   blocks, reducing archival time and bandwidth usage.
 
                   Should the cache become desynchronized or corrupted, tarsnap
                   will refuse to run until you manually rebuild the cache with
-                  <command>tarsnap --fsck</command>.
+                  {command}`tarsnap --fsck`.
 
-                  Set to <literal>null</literal> to disable caching.
+                  Set to `null` to disable caching.
                 '';
               };
 
               nodump = mkOption {
                 type = types.bool;
                 default = true;
-                description = ''
-                  Exclude files with the <literal>nodump</literal> flag.
+                description = lib.mdDoc ''
+                  Exclude files with the `nodump` flag.
                 '';
               };
 
               printStats = mkOption {
                 type = types.bool;
                 default = true;
-                description = ''
+                description = lib.mdDoc ''
                   Print global archive statistics upon completion.
                   The output is available via
-                  <command>systemctl status tarsnap-archive-name</command>.
+                  {command}`systemctl status tarsnap-archive-name`.
                 '';
               };
 
               checkpointBytes = mkOption {
                 type = types.nullOr types.str;
                 default = "1GB";
-                description = ''
-                  Create a checkpoint every <literal>checkpointBytes</literal>
+                description = lib.mdDoc ''
+                  Create a checkpoint every `checkpointBytes`
                   of uploaded data (optionally specified using an SI prefix).
 
                   1GB is the minimum value. A higher value is recommended,
                   as checkpointing is expensive.
 
-                  Set to <literal>null</literal> to disable checkpointing.
+                  Set to `null` to disable checkpointing.
                 '';
               };
 
@@ -152,7 +152,7 @@ in
               aggressiveNetworking = mkOption {
                 type = types.bool;
                 default = false;
-                description = ''
+                description = lib.mdDoc ''
                   Upload data over multiple TCP connections, potentially
                   increasing tarsnap's bandwidth utilisation at the cost
                   of slowing down all other network traffic. Not
@@ -164,13 +164,13 @@ in
               directories = mkOption {
                 type = types.listOf types.path;
                 default = [];
-                description = "List of filesystem paths to archive.";
+                description = lib.mdDoc "List of filesystem paths to archive.";
               };
 
               excludes = mkOption {
                 type = types.listOf types.str;
                 default = [];
-                description = ''
+                description = lib.mdDoc ''
                   Exclude files and directories matching these patterns.
                 '';
               };
@@ -178,7 +178,7 @@ in
               includes = mkOption {
                 type = types.listOf types.str;
                 default = [];
-                description = ''
+                description = lib.mdDoc ''
                   Include only files and directories matching these
                   patterns (the empty list includes everything).
 
@@ -189,7 +189,7 @@ in
               lowmem = mkOption {
                 type = types.bool;
                 default = false;
-                description = ''
+                description = lib.mdDoc ''
                   Reduce memory consumption by not caching small files.
                   Possibly beneficial if the average file size is smaller
                   than 1 MB and the number of files is lower than the
@@ -200,9 +200,9 @@ in
               verylowmem = mkOption {
                 type = types.bool;
                 default = false;
-                description = ''
+                description = lib.mdDoc ''
                   Reduce memory consumption by a factor of 2 beyond what
-                  <literal>lowmem</literal> does, at the cost of significantly
+                  `lowmem` does, at the cost of significantly
                   slowing down the archiving process.
                 '';
               };
@@ -210,7 +210,7 @@ in
               maxbw = mkOption {
                 type = types.nullOr types.int;
                 default = null;
-                description = ''
+                description = lib.mdDoc ''
                   Abort archival if upstream bandwidth usage in bytes
                   exceeds this threshold.
                 '';
@@ -220,7 +220,7 @@ in
                 type = types.nullOr types.int;
                 default = null;
                 example = literalExpression "25 * 1000";
-                description = ''
+                description = lib.mdDoc ''
                   Upload bandwidth rate limit in bytes.
                 '';
               };
@@ -229,7 +229,7 @@ in
                 type = types.nullOr types.int;
                 default = null;
                 example = literalExpression "50 * 1000";
-                description = ''
+                description = lib.mdDoc ''
                   Download bandwidth rate limit in bytes.
                 '';
               };
@@ -237,21 +237,21 @@ in
               verbose = mkOption {
                 type = types.bool;
                 default = false;
-                description = ''
+                description = lib.mdDoc ''
                   Whether to produce verbose logging output.
                 '';
               };
               explicitSymlinks = mkOption {
                 type = types.bool;
                 default = false;
-                description = ''
+                description = lib.mdDoc ''
                   Whether to follow symlinks specified as archives.
                 '';
               };
               followSymlinks = mkOption {
                 type = types.bool;
                 default = false;
-                description = ''
+                description = lib.mdDoc ''
                   Whether to follow all symlinks in archive trees.
                 '';
               };
@@ -274,17 +274,17 @@ in
           }
         '';
 
-        description = ''
+        description = lib.mdDoc ''
           Tarsnap archive configurations. Each attribute names an archive
           to be created at a given time interval, according to the options
           associated with it. When uploading to the tarsnap server,
           archive names are suffixed by a 1 second resolution timestamp,
-          with the format <literal>%Y%m%d%H%M%S</literal>.
+          with the format `%Y%m%d%H%M%S`.
 
           For each member of the set is created a timer which triggers the
-          instanced <literal>tarsnap-archive-name</literal> service unit. You may use
-          <command>systemctl start tarsnap-archive-name</command> to
-          manually trigger creation of <literal>archive-name</literal> at
+          instanced `tarsnap-archive-name` service unit. You may use
+          {command}`systemctl start tarsnap-archive-name` to
+          manually trigger creation of `archive-name` at
           any time.
         '';
       };
diff --git a/nixos/modules/services/backup/tsm.nix b/nixos/modules/services/backup/tsm.nix
index 4e690ac6ecda1..bd6f3d71fe6c6 100644
--- a/nixos/modules/services/backup/tsm.nix
+++ b/nixos/modules/services/backup/tsm.nix
@@ -18,38 +18,38 @@ let
       type = nonEmptyStr;
       default = "backup";
       example = "incr";
-      description = ''
+      description = lib.mdDoc ''
         The actual command passed to the
-        <literal>dsmc</literal> executable to start the backup.
+        `dsmc` executable to start the backup.
       '';
     };
     servername = mkOption {
       type = nonEmptyStr;
       example = "mainTsmServer";
-      description = ''
+      description = lib.mdDoc ''
         Create a systemd system service
-        <literal>tsm-backup.service</literal> that starts
+        `tsm-backup.service` that starts
         a backup based on the given servername's stanza.
         Note that this server's
-        <option>passwdDir</option> will default to
-        <filename>/var/lib/tsm-backup/password</filename>
+        {option}`passwdDir` will default to
+        {file}`/var/lib/tsm-backup/password`
         (but may be overridden);
         also, the service will use
-        <filename>/var/lib/tsm-backup</filename> as
-        <literal>HOME</literal> when calling
-        <literal>dsmc</literal>.
+        {file}`/var/lib/tsm-backup` as
+        `HOME` when calling
+        `dsmc`.
       '';
     };
     autoTime = mkOption {
       type = nullOr nonEmptyStr;
       default = null;
       example = "12:00";
-      description = ''
+      description = lib.mdDoc ''
         The backup service will be invoked
         automatically at the given date/time,
         which must be in the format described in
-        <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
-        The default <literal>null</literal>
+        {manpage}`systemd.time(5)`.
+        The default `null`
         disables automatic backups.
       '';
     };
diff --git a/nixos/modules/services/backup/zfs-replication.nix b/nixos/modules/services/backup/zfs-replication.nix
index 6d75774c78f91..1a089bb34866b 100644
--- a/nixos/modules/services/backup/zfs-replication.nix
+++ b/nixos/modules/services/backup/zfs-replication.nix
@@ -12,43 +12,43 @@ in {
       enable = mkEnableOption "ZFS snapshot replication.";
 
       followDelete = mkOption {
-        description = "Remove remote snapshots that don't have a local correspondant.";
+        description = lib.mdDoc "Remove remote snapshots that don't have a local correspondant.";
         default = true;
         type = types.bool;
       };
 
       host = mkOption {
-        description = "Remote host where snapshots should be sent. <literal>lz4</literal> is expected to be installed on this host.";
+        description = lib.mdDoc "Remote host where snapshots should be sent. `lz4` is expected to be installed on this host.";
         example = "example.com";
         type = types.str;
       };
 
       identityFilePath = mkOption {
-        description = "Path to SSH key used to login to host.";
+        description = lib.mdDoc "Path to SSH key used to login to host.";
         example = "/home/username/.ssh/id_rsa";
         type = types.path;
       };
 
       localFilesystem = mkOption {
-        description = "Local ZFS fileystem from which snapshots should be sent.  Defaults to the attribute name.";
+        description = lib.mdDoc "Local ZFS fileystem from which snapshots should be sent.  Defaults to the attribute name.";
         example = "pool/file/path";
         type = types.str;
       };
 
       remoteFilesystem = mkOption {
-        description = "Remote ZFS filesystem where snapshots should be sent.";
+        description = lib.mdDoc "Remote ZFS filesystem where snapshots should be sent.";
         example = "pool/file/path";
         type = types.str;
       };
 
       recursive = mkOption {
-        description = "Recursively discover snapshots to send.";
+        description = lib.mdDoc "Recursively discover snapshots to send.";
         default = true;
         type = types.bool;
       };
 
       username = mkOption {
-        description = "Username used by SSH to login to remote host.";
+        description = lib.mdDoc "Username used by SSH to login to remote host.";
         example = "username";
         type = types.str;
       };
diff --git a/nixos/modules/services/backup/znapzend.nix b/nixos/modules/services/backup/znapzend.nix
index 09e60177c3909..ecd90ba5b30a3 100644
--- a/nixos/modules/services/backup/znapzend.nix
+++ b/nixos/modules/services/backup/znapzend.nix
@@ -52,7 +52,7 @@ let
 
       label = mkOption {
         type = str;
-        description = "Label for this destination. Defaults to the attribute name.";
+        description = lib.mdDoc "Label for this destination. Defaults to the attribute name.";
       };
 
       plan = mkOption {
@@ -63,15 +63,15 @@ let
 
       dataset = mkOption {
         type = str;
-        description = "Dataset name to send snapshots to.";
+        description = lib.mdDoc "Dataset name to send snapshots to.";
         example = "tank/main";
       };
 
       host = mkOption {
         type = nullOr str;
-        description = ''
+        description = lib.mdDoc ''
           Host to use for the destination dataset. Can be prefixed with
-          <literal>user@</literal> to specify the ssh user.
+          `user@` to specify the ssh user.
         '';
         default = null;
         example = "john@example.com";
@@ -79,11 +79,11 @@ let
 
       presend = mkOption {
         type = nullOr str;
-        description = ''
+        description = lib.mdDoc ''
           Command to run before sending the snapshot to the destination.
-          Intended to run a remote script via <command>ssh</command> on the
+          Intended to run a remote script via {command}`ssh` on the
           destination, e.g. to bring up a backup disk or server or to put a
-          zpool online/offline. See also <option>postsend</option>.
+          zpool online/offline. See also {option}`postsend`.
         '';
         default = null;
         example = "ssh root@bserv zpool import -Nf tank";
@@ -91,11 +91,11 @@ let
 
       postsend = mkOption {
         type = nullOr str;
-        description = ''
+        description = lib.mdDoc ''
           Command to run after sending the snapshot to the destination.
-          Intended to run a remote script via <command>ssh</command> on the
+          Intended to run a remote script via {command}`ssh` on the
           destination, e.g. to bring up a backup disk or server or to put a
-          zpool online/offline. See also <option>presend</option>.
+          zpool online/offline. See also {option}`presend`.
         '';
         default = null;
         example = "ssh root@bserv zpool export tank";
@@ -115,32 +115,32 @@ let
 
       enable = mkOption {
         type = bool;
-        description = "Whether to enable this source.";
+        description = lib.mdDoc "Whether to enable this source.";
         default = true;
       };
 
       recursive = mkOption {
         type = bool;
-        description = "Whether to do recursive snapshots.";
+        description = lib.mdDoc "Whether to do recursive snapshots.";
         default = false;
       };
 
       mbuffer = {
         enable = mkOption {
           type = bool;
-          description = "Whether to use <command>mbuffer</command>.";
+          description = lib.mdDoc "Whether to use {command}`mbuffer`.";
           default = false;
         };
 
         port = mkOption {
           type = nullOr ints.u16;
-          description = ''
-              Port to use for <command>mbuffer</command>.
+          description = lib.mdDoc ''
+              Port to use for {command}`mbuffer`.
 
-              If this is null, it will run <command>mbuffer</command> through
+              If this is null, it will run {command}`mbuffer` through
               ssh.
 
-              If this is not null, it will run <command>mbuffer</command>
+              If this is not null, it will run {command}`mbuffer`
               directly through TCP, which is not encrypted but faster. In that
               case the given port needs to be open on the destination host.
           '';
@@ -149,8 +149,8 @@ let
 
         size = mkOption {
           type = mbufferSizeType;
-          description = ''
-            The size for <command>mbuffer</command>.
+          description = lib.mdDoc ''
+            The size for {command}`mbuffer`.
             Supports the units b, k, M, G.
           '';
           default = "1G";
@@ -160,10 +160,10 @@ let
 
       presnap = mkOption {
         type = nullOr str;
-        description = ''
+        description = lib.mdDoc ''
           Command to run before snapshots are taken on the source dataset,
           e.g. for database locking/flushing. See also
-          <option>postsnap</option>.
+          {option}`postsnap`.
         '';
         default = null;
         example = literalExpression ''
@@ -173,9 +173,9 @@ let
 
       postsnap = mkOption {
         type = nullOr str;
-        description = ''
+        description = lib.mdDoc ''
           Command to run after snapshots are taken on the source dataset,
-          e.g. for database unlocking. See also <option>presnap</option>.
+          e.g. for database unlocking. See also {option}`presnap`.
         '';
         default = null;
         example = literalExpression ''
@@ -185,13 +185,13 @@ let
 
       timestampFormat = mkOption {
         type = timestampType;
-        description = ''
+        description = lib.mdDoc ''
           The timestamp format to use for constructing snapshot names.
-          The syntax is <literal>strftime</literal>-like. The string must
-          consist of the mandatory <literal>%Y %m %d %H %M %S</literal>.
-          Optionally  <literal>- _ . :</literal>  characters as well as any
+          The syntax is `strftime`-like. The string must
+          consist of the mandatory `%Y %m %d %H %M %S`.
+          Optionally  `- _ . :`  characters as well as any
           alphanumeric character are allowed. If suffixed by a
-          <literal>Z</literal>, times will be in UTC.
+          `Z`, times will be in UTC.
         '';
         default = "%Y-%m-%d-%H%M%S";
         example = "znapzend-%m.%d.%Y-%H%M%SZ";
@@ -199,7 +199,7 @@ let
 
       sendDelay = mkOption {
         type = int;
-        description = ''
+        description = lib.mdDoc ''
           Specify delay (in seconds) before sending snaps to the destination.
           May be useful if you want to control sending time.
         '';
@@ -215,13 +215,13 @@ let
 
       dataset = mkOption {
         type = str;
-        description = "The dataset to use for this source.";
+        description = lib.mdDoc "The dataset to use for this source.";
         example = "tank/home";
       };
 
       destinations = mkOption {
         type = attrsOf (destType config);
-        description = "Additional destinations.";
+        description = lib.mdDoc "Additional destinations.";
         default = {};
         example = literalExpression ''
           {
@@ -300,7 +300,7 @@ in
         default = "debug";
         example = "warning";
         type = enum ["debug" "info" "warning" "err" "alert"];
-        description = ''
+        description = lib.mdDoc ''
           The log level when logging to file. Any of debug, info, warning, err,
           alert. Default in daemonized form is debug.
         '';
@@ -318,18 +318,18 @@ in
       noDestroy = mkOption {
         type = bool;
         default = false;
-        description = "Does all changes to the filesystem except destroy.";
+        description = lib.mdDoc "Does all changes to the filesystem except destroy.";
       };
 
       autoCreation = mkOption {
         type = bool;
         default = false;
-        description = "Automatically create the destination dataset if it does not exist.";
+        description = lib.mdDoc "Automatically create the destination dataset if it does not exist.";
       };
 
       zetup = mkOption {
         type = attrsOf srcType;
-        description = "Znapzend configuration.";
+        description = lib.mdDoc "Znapzend configuration.";
         default = {};
         example = literalExpression ''
           {
@@ -350,7 +350,7 @@ in
 
       pure = mkOption {
         type = bool;
-        description = ''
+        description = lib.mdDoc ''
           Do not persist any stateful znapzend setups. If this option is
           enabled, your previously set znapzend setups will be cleared and only
           the ones defined with this module will be applied.
diff --git a/nixos/modules/services/backup/zrepl.nix b/nixos/modules/services/backup/zrepl.nix
index 1b4216ed1714a..e3a9009126455 100644
--- a/nixos/modules/services/backup/zrepl.nix
+++ b/nixos/modules/services/backup/zrepl.nix
@@ -17,7 +17,7 @@ in
         type = types.package;
         default = pkgs.zrepl;
         defaultText = literalExpression "pkgs.zrepl";
-        description = "Which package to use for zrepl";
+        description = lib.mdDoc "Which package to use for zrepl";
       };
 
       settings = mkOption {